Bir listenin içeriğini alın ve başka bir listeye ekleyin


193

Bir listenin içeriğini alıp başka bir listeye eklemenin mantıklı olup olmadığını anlamaya çalışıyorum.

Ben bir dosyadan belirli satırları alacak ve onları bir listede kaydedecek bir döngü fonksiyonu ile oluşturulan ilk liste var.

Daha sonra bu satırları kaydetmek ve başka bir dosya üzerinde yeni bir döngü başlatmak için ikinci bir liste kullanılır.

Benim fikrim for döngüsü tamamlandıktan sonra listeyi almak, ikinci listeye dökmek, sonra yeni bir döngü başlatmak, ilk listenin içeriğini tekrar ikinciye dökmek, ancak eklemek, böylece ikinci liste döngümde oluşturulan tüm küçük liste dosyalarının toplamı. Listeye yalnızca belirli koşullar karşılandığında eklenmelidir.

Buna benzer bir şeye benziyor:

# 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

Bu mantıklı mı yoksa farklı bir rotaya gitmem mi gerekiyor?

Günlükleri listesi uzun ve her metin dosyası oldukça büyük olduğundan, çok fazla döngü almayacak verimli bir şeye ihtiyacım var; bu yüzden listelerin amaca uygun olacağını düşündüm.

Yanıtlar:


371

Muhtemelen istiyorsun

list2.extend(list1)

onun yerine

list2.append(list1)

Fark şu:

>>> 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]

Yana list.extend()keyfi iterable kabul, ayrıca yerini alabilir

for line in mylog:
    list1.append(line)

tarafından

list1.extend(mylog)

Evet, ekleme bir öğe içindir, genişletme concat gibidir.
Catalina Chircu

13

Birçok küçük listeyi, küçük listeleri kopyalamadan tek bir büyük liste (veya en azından tek bir büyük yinelenebilir) olarak işlemenin hızlı bir yolu için itertools.chain'e bir göz atın :

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

Bu gerçekten kaygan geliyor! Ben zaten itertools kullanarak sahip kodu değiştirebilirsiniz olmadığını görmek için bir göz atacağım!
user1006198

3

Yapmaya çalıştığınız şey için oldukça makul görünüyor.

Ağır kaldırma işlemlerinden daha fazlasını yapmak için Python'a yaslanan biraz daha kısa bir versiyon olabilir:

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)Üzerinde dolaşır listve yayar TrueBir eşleşme bulunduğunda her. ilk eleman bulunur bulunmaz any()geri dönmek için kısa devre değerlendirmesini kullanır . içeriğini sonuna ekler .TrueTruelist2.extend()list1


1
any(True for line in list1 if "string" in line)olarak daha düzgün yazılmıştır any("string" in line for line in list1).
Karl Knechtel

İyi bir nokta, @KarlKnechtel, farklı olmalarına rağmen. Sürümünüz her zaman Doğru veya Yanlış bir şey yayınlar. Benimki sadece tek bir Doğru yayar. Bu kıyaslamaların nasıl yapıldığı veya önemli bir fark olup olmadığı hakkında hiçbir fikrim yok.
Kirk Strauser

Her iki durumda da, anybir jeneratör alır; hiçbir yerde Doğru veya Yanlış değer listesi oluşturulmaz. Sürümüm anykontrol etmek için daha fazla şey döndürüyor , ancak bunun karşılığında jeneratörün kendisinde aynı kontrolü yapmamak. Bunun bir yıkama olduğunu hayal ediyorum, ama timeitburada yetkili, ben değil. :)
Karl Knechtel

3

'+' Operatörünü kullanarak iki listeyi de (örneğin a, b) birleştirebilirsiniz. Örneğin,

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

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

3

Önceki cevapları özetlemek için. Bir listeniz [0,1,2]ve başka bir listeniz varsa [3,4,5]ve bunları birleştirmek istiyorsanız, bu olur [0,1,2,3,4,5], ihtiyaçlarınız için akıllıca kullanma farklılıklarını kullanabilir chainingveya extendingbilmeniz gerekir.

Bir listeyi genişletme

listSınıflar extendyöntemini kullanarak, bir listeden diğerine öğelerin bir kopyasını yapabilirsiniz. Ancak bu, çoğu durumda iyi olması gereken fazladan bellek kullanımına neden olur, ancak bellek açısından verimli olmak istiyorsanız sorunlara neden olabilir.

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

resim açıklamasını buraya girin

Bir listeye zincirleme

Aksine , listelerin üzerinde yineleme yapmak için kullanılabilecek itertools.chainbir sözde döndürecek birçok listeyi kablolamak için kullanabilirsiniz iterator. Bu, öğeleri kopyalamak yerine sadece bir sonraki listeye işaret ettiği için bellekte daha verimlidir.

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

resim açıklamasını buraya girin

İlk yinelemeden bitene kadar öğeleri döndüren, sonra tüm yinelenebilirler bitene kadar bir sonraki yinelemeye giden bir yineleyici yapın. Ardışık sekansları tek bir sekans olarak tedavi etmek için kullanılır.


2

Kullanılması map()ve reduce()yerleşik işlevleri

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)

Minimal "döngü için" ve zarif kodlama deseni :)


0

Aşağıdaki gibi bir listemiz varsa:

list  = [2,2,3,4]

başka bir listeye kopyalamanın iki yolu.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.