Возьмите содержимое списка и добавьте его в другой список.


193

Я пытаюсь понять, имеет ли смысл брать содержимое списка и добавлять его в другой список.

У меня есть первый список, созданный с помощью функции цикла, которая будет извлекать определенные строки из файла и сохранять их в списке.

Затем второй список используется для сохранения этих строк и запуска нового цикла поверх другого файла.

Моя идея состояла в том, чтобы получить список, как только цикл for будет выполнен, выгрузить его во второй список, затем запустить новый цикл, снова вывести содержимое первого списка во второй, но добавив его, так что второй список будет сумма всех меньших файлов списка, созданных в моем цикле. Список должен быть добавлен только при соблюдении определенных условий.

Это выглядит примерно так:

# 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)

Да, добавление для одного элемента, расширение похоже на concat.
Каталина Чирку

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!
user1006198

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получает генератор; нигде не создается список значений True или False. Моя версия возвращает больше вещей для 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должны знать различия, чтобы использовать его с умом для своих нужд.

Расширение списка

Используя метод listclasses 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.