Візьміть вміст списку та додайте його до іншого списку


193

Я намагаюся зрозуміти, чи є сенс взяти вміст списку і додати його до іншого списку.

У мене є перший список, створений за допомогою функції циклу, який виведе конкретні рядки з файлу і збереже їх у списку.

Потім використовується другий список, щоб зберегти ці рядки, і почати новий цикл над іншим файлом.

Моя ідея полягала в тому, щоб отримати список, коли цикл для циклу виконаний, скинути його у другий список, потім запустити новий цикл, знову скинути вміст першого списку у другий, але доповнити його, тож другий список стане сума всіх менших файлів списку, створених у моєму циклі. Список слід доповнити лише за умови дотримання певних умов.

Це схоже на щось подібне до цього:

# This is done for each log in my directory, i have a loop running
for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    for item in list1:
        if "string" in item: #if somewhere in the list1 i have a match for a string
            list2.append(list1) # append every line in list1 to list2
            del list1 [:] # delete the content of the list1
            break
        else:
            del list1 [:] # delete the list content and start all over

Це має сенс чи я повинен піти іншим маршрутом?

Мені потрібно щось ефективне, яке не займе занадто багато циклів, оскільки список журналів довгий і кожен текстовий файл досить великий; тому я подумав, що списки відповідатимуть меті.

Відповіді:


371

Ви, мабуть, хочете

list2.extend(list1)

замість

list2.append(list1)

Ось різниця:

>>> a = range(5)
>>> b = range(3)
>>> c = range(2)
>>> b.append(a)
>>> b
[0, 1, 2, [0, 1, 2, 3, 4]]
>>> c.extend(a)
>>> c
[0, 1, 0, 1, 2, 3, 4]

Оскільки list.extend()ви приймаєте довільну ітерабельність, ви також можете її замінити

for line in mylog:
    list1.append(line)

від

list1.extend(mylog)

Так, додавання призначено для одного елемента, розширення - як стислість.
Каталіна Чірку

13

Погляньте на itertools.chain, щоб швидко розглядати багато невеликих списків як єдиний великий список (або принаймні як один великий ітерабельний) без копіювання менших списків:

>>> import itertools
>>> p = ['a', 'b', 'c']
>>> q = ['d', 'e', 'f']
>>> r = ['g', 'h', 'i']
>>> for x in itertools.chain(p, q, r):
        print x.upper()

Це звучить дуже гладко! Я погляну на це, щоб побачити, чи можу я замінити код, який у мене вже використовується itertools!
користувач1006198

3

Це здається досить розумним для того, що ви намагаєтесь зробити.

Трохи коротша версія, яка спирається на Python, щоб зробити більше важкого підйому, може бути:

for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    if any(True for line in list1 if "string" in line):
        list2.extend(list1)
    del list1

    ....

У (True for line in list1 if "string" in line)перебирає listі випромінює Trueкожен раз , коли знайдено збіг. any()використовує оцінку короткого замикання для повернення, Trueяк тільки Trueзнайдений перший елемент. list2.extend()додає вміст list1до кінця.


1
any(True for line in list1 if "string" in line)чіткіше написано як any("string" in line for line in list1).
Карл Кнечтел

Хороший момент, @KarlKnechtel, хоча вони дещо різні. Ваша версія завжди випромінює щось , істинне чи помилкове. Моє випромінює лише одну Правду. Я поняття не маю, як ці показники визначаються, чи є достатньо різниці для того, щоб мати значення.
Кірк Штраузер

В обох випадках anyотримує генератор; жоден список істинних чи хибних значень не будується ніде. Моя версія повертає більше речей для anyперевірки, але взамін за те, що не робити ту саму перевірку в самому генераторі. Я думаю, що це миття, але timeitтут авторитетно, а не я. :)
Карл Кнечтел

3

Ви також можете об'єднати два списки (скажімо, a, b) за допомогою оператора "+". Наприклад,

a = [1,2,3,4]
b = [4,5,6,7]
c = a + b

Output:
>>> c
[1, 2, 3, 4, 4, 5, 6, 7]

3

Для резюме попередніх відповідей. Якщо у вас є список із [0,1,2]і ще одним із, [3,4,5]і ви хочете їх об'єднати, таким чином він стає [0,1,2,3,4,5], ви можете використовувати chainingабо extendingслід знати відмінності, щоб їх розумно використовувати для своїх потреб.

Розширення списку

Використовуючи метод listкласів extend, ви можете зробити копію елементів з одного списку в інший. Однак це спричинить додаткове використання пам’яті, що в більшості випадків має бути добре, але може призвести до проблем, якщо ви хочете бути ефективними в пам'яті.

a = [0,1,2]
b = [3,4,5]
a.extend(b)
>>[0,1,2,3,4,5]

введіть тут опис зображення

Складання списку

Навпаки, ви можете використовувати itertools.chainдля передачі багатьох списків, які повернуть так званий, iteratorякий можна використовувати для повторення списків. Це більш ефективно в пам'яті, оскільки це не копіювання елементів, а просто вказівка ​​на наступний список.

import itertools
a = [0,1,2]
b = [3,4,5]
c = itertools.chain(a, b)

введіть тут опис зображення

Зробіть ітератор, який повертає елементи з першого ітерабельного до вичерпання, потім переходить до наступного ітерабельного, поки всі ітерабелі не будуть вичерпані. Використовується для обробки послідовних послідовностей як однієї послідовності.


2

Використання map()і reduce()вбудовані функції

def file_to_list(file):
     #stuff to parse file to a list
     return list

files = [...list of files...]

L = map(file_to_list, files)

flat_L = reduce(lambda x,y:x+y, L)

Мінімальний "для циклу" та елегантний шаблон кодування :)


0

Якщо у нас є такий список, як нижче:

list  = [2,2,3,4]

два способи скопіювати його в інший список.

1.

x = [list]  # x =[] x.append(list) same 
print("length is {}".format(len(x)))
for i in x:
    print(i)
length is 1
[2, 2, 3, 4]

2.

x = [l for l in list]
print("length is {}".format(len(x)))
for i in x:
    print(i)
length is 4
2
2
3
4
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.