リストのコンテンツを取得して別のリストに追加する


191

リストのコンテンツを取得して別のリストに追加することが理にかなっているかどうかを理解しようとしています。

ループ関数を使用して最初のリストを作成しました。これにより、ファイルから特定の行が取得され、それらがリストに保存されます。

次に、2番目のリストを使用してこれらの行を保存し、別のファイルで新しいサイクルを開始します。

私のアイデアは、forサイクルが完了したらリストを取得し、それを2番目のリストにダンプし、次に新しいサイクルを開始し、最初のリストの内容を2番目に再度ダンプしますが、追加するので、2番目のリストはループで作成されたすべての小さいリストファイルの合計。リストは、特定の条件が満たされた場合にのみ追加する必要があります。

これは次のようなものです。

# 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

これは理にかなっていますか、それとも別のルートを選ぶべきですか?

ログのリストが長く、各テキストファイルがかなり大きいので、あまりサイクルをかけない効率的なものが必要です。リストは目的に合うと思いました。

回答:


369

あなたはおそらく欲しい

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()、任意のiterableを受け入れ、あなたも置き換えることができます

for line in mylog:
    list1.append(line)

沿って

list1.extend(mylog)

はい、追加は1つの要素用で、拡張は連結のようです。
Catalina Chircu

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)ます。
Karl Knechtel、2011年

良い点は、@ KarlKnechtelですが、微妙に異なります。お使いのバージョンでは常に発する何かを TrueまたはFalseのいずれかで、。鉱山は1つのTrueだけを放出します。私はそれらのベンチマークがどのように評価されているのか、または問題になるほど十分な違いがあるのか​​どうかを知りません。
Kirk Strauser

どちらの場合も、anyジェネレータを受け取ります。TrueまたはFalse値のリストはどこにも作成されません。私のバージョンはany、チェックするためにより多くのものを返しますが、ジェネレーター自体で同じチェックを行わない代わりに。私はそれがウォッシュだと想像しtimeitますが、私ではなく、ここでは権威があります。:)
Karl Knechtel、2011年

3

「+」演算子を使用して、2つのリスト(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]場合は、を使用するchainingextending、必要に応じてそれを賢く使用するための違いを知っている必要があります。

リストを拡張する

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]

別のリストにコピーする2つの方法。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.