Bawa konten daftar dan tambahkan ke daftar lain


193

Saya mencoba memahami jika masuk akal untuk mengambil konten dari daftar dan menambahkannya ke daftar lain.

Saya memiliki daftar pertama yang dibuat melalui fungsi loop, yang akan mendapatkan baris tertentu dari file dan akan menyimpannya dalam daftar.

Kemudian daftar kedua digunakan untuk menyimpan baris-baris ini, dan memulai siklus baru di atas file lain.

Gagasan saya adalah untuk mendapatkan daftar setelah siklus selesai, masukkan ke daftar kedua, kemudian mulai siklus baru, buang konten dari daftar pertama lagi ke yang kedua tetapi menambahkannya, sehingga daftar kedua akan menjadi jumlah semua file daftar kecil yang dibuat di loop saya. Daftar harus ditambahkan hanya jika kondisi tertentu terpenuhi.

Sepertinya ini mirip dengan ini:

# 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

Apakah ini masuk akal atau saya harus pergi untuk rute yang berbeda?

Saya memerlukan sesuatu yang efisien yang tidak akan memakan banyak siklus, karena daftar log panjang dan setiap file teks cukup besar; jadi saya pikir daftar itu sesuai dengan tujuannya.

Jawaban:


371

Anda mungkin mau

list2.extend(list1)

dari pada

list2.append(list1)

Inilah perbedaannya:

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

Karena list.extend()menerima pengalihan yang sewenang-wenang, Anda juga dapat mengganti

for line in mylog:
    list1.append(line)

oleh

list1.extend(mylog)

Ya, append adalah untuk satu elemen, extended seperti concat.
Catalina Chircu

13

Lihatlah itertools.chain untuk cara cepat memperlakukan banyak daftar kecil sebagai satu daftar besar (atau setidaknya sebagai satu besar yang dapat diubah) tanpa menyalin daftar yang lebih kecil:

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

Kedengarannya sangat licin! Saya akan melihatnya untuk melihat apakah saya dapat mengganti kode yang sudah saya gunakan itertools!
user1006198

3

Tampaknya cukup masuk akal untuk apa yang Anda coba lakukan.

Versi yang sedikit lebih pendek yang bersandar pada Python untuk melakukan lebih banyak tugas berat mungkin:

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

    ....

The (True for line in list1 if "string" in line)iterates atas listdan memancarkan Truesetiap kali kecocokan ditemukan. any()menggunakan evaluasi hubung singkat untuk kembali Truesegera setelah Trueelemen pertama ditemukan. list2.extend()menambahkan konten list1hingga akhir.


1
any(True for line in list1 if "string" in line)lebih rapi ditulis sebagai any("string" in line for line in list1).
Karl Knechtel

Poin bagus, @KarlKnechtel, meskipun keduanya agak berbeda. Versi Anda selalu memancarkan sesuatu , Baik Benar atau Salah. Milik saya hanya memancarkan satu Benar. Saya tidak tahu bagaimana tolok ukur itu, atau apakah ada perbedaan yang cukup penting sama sekali.
Kirk Strauser

Dalam kedua kasus, anyterima generator; tidak ada daftar nilai Benar atau Salah dibangun di mana saja. Versi saya mengembalikan lebih banyak hal untuk anydiperiksa, tetapi sebagai imbalan karena tidak melakukan pemeriksaan yang sama di generator itu sendiri. Saya membayangkan ini adalah pencucian, tetapi timeitotoritatif di sini, bukan saya. :)
Karl Knechtel

3

Anda juga dapat menggabungkan dua daftar (misalnya a, b) menggunakan operator '+'. Sebagai contoh,

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

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

3

Untuk meringkas jawaban sebelumnya. Jika Anda memiliki daftar dengan [0,1,2]dan satu lagi dengan [3,4,5]dan Anda ingin menggabungkannya, maka itu menjadi [0,1,2,3,4,5], Anda dapat menggunakan chainingatauextending dan harus mengetahui perbedaan untuk menggunakannya secara bijak untuk kebutuhan Anda.

Memperluas daftar

Menggunakan metode listkelas extend, Anda dapat melakukan salinan elemen dari satu daftar ke yang lain. Namun ini akan menyebabkan penggunaan memori ekstra, yang seharusnya baik-baik saja dalam kebanyakan kasus, tetapi dapat menyebabkan masalah jika Anda ingin menjadi efisien memori.

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

masukkan deskripsi gambar di sini

Daftar chaining

Sebaliknya Anda dapat menggunakan itertools.chainuntuk mentransfer banyak daftar, yang akan mengembalikan apa yang disebut iteratordapat digunakan untuk beralih di atas daftar. Ini lebih hemat memori karena tidak menyalin elemen tetapi hanya menunjuk ke daftar berikutnya.

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

masukkan deskripsi gambar di sini

Buat sebuah iterator yang mengembalikan elemen dari yang pertama iterable sampai habis, lalu lanjutkan ke iterable berikutnya, sampai semua iterables habis. Digunakan untuk memperlakukan urutan berurutan sebagai urutan tunggal.


2

Menggunakan fungsi map()dan reduce()bawaan

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 "untuk pengulangan" dan pola pengkodean yang elegan :)


0

Jika kami memiliki daftar seperti di bawah ini:

list  = [2,2,3,4]

dua cara untuk menyalinnya ke daftar lain.

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.