Nehmen Sie den Inhalt einer Liste und hängen Sie ihn an eine andere Liste an

191

Ich versuche zu verstehen, ob es sinnvoll ist, den Inhalt einer Liste zu übernehmen und an eine andere Liste anzuhängen.

Ich habe die erste Liste durch eine Schleifenfunktion erstellt, die bestimmte Zeilen aus einer Datei herausholt und sie in einer Liste speichert.

Dann wird eine zweite Liste verwendet, um diese Zeilen zu speichern und einen neuen Zyklus über eine andere Datei zu starten.

Meine Idee war es, die Liste zu erhalten, sobald der for-Zyklus abgeschlossen ist, sie in die zweite Liste zu kopieren, dann einen neuen Zyklus zu starten, den Inhalt der ersten Liste erneut in die zweite zu kopieren, ihn aber anzuhängen, sodass die zweite Liste die ist Summe aller kleineren Listendateien, die in meiner Schleife erstellt wurden. Die Liste muss nur angehängt werden, wenn bestimmte Bedingungen erfüllt sind.

Es sieht ungefähr so ​​aus:

# 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

Ist das sinnvoll oder sollte ich einen anderen Weg gehen?

Ich brauche etwas Effizientes, das nicht zu viele Zyklen in Anspruch nimmt, da die Liste der Protokolle lang und jede Textdatei ziemlich groß ist. Also dachte ich, dass die Listen dem Zweck entsprechen würden.

user1006198
quelle

Antworten:

369

Sie wollen wahrscheinlich

list2.extend(list1)

anstatt

list2.append(list1)

Hier ist der Unterschied:

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

Da list.extend()eine beliebige iterable akzeptiert wird, können Sie diese auch ersetzen

for line in mylog:
    list1.append(line)

durch

list1.extend(mylog)
Sven Marnach
quelle
Ja, Anhängen ist für ein Element, Erweitern ist wie Concat.
Catalina Chircu
13

In itertools.chain finden Sie eine schnelle Möglichkeit, viele kleine Listen als einzelne große Liste (oder zumindest als einzelne große iterierbare Liste) zu behandeln, ohne die kleineren Listen zu kopieren:

>>> 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()
Raymond Hettinger
quelle
Das klingt wirklich schick! Ich werde es mir ansehen, um zu sehen, ob ich den Code, den ich bereits habe, mit itertools ersetzen kann!
user1006198
3

Das scheint ziemlich vernünftig für das, was Sie versuchen zu tun.

Eine etwas kürzere Version, die sich auf Python stützt, um mehr vom schweren Heben zu tun, könnte sein:

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

    ....

Das (True for line in list1 if "string" in line)iteriert listund wird ausgegeben, Truewenn eine Übereinstimmung gefunden wird. any()verwendet die Kurzschlussauswertung, um zurückzukehren True, sobald das erste TrueElement gefunden wurde. list2.extend()Hängt den Inhalt von list1an das Ende an.

Kirk Strauser
quelle
1
any(True for line in list1 if "string" in line)ist ordentlicher geschrieben als any("string" in line for line in list1).
Karl Knechtel
Guter Punkt, @KarlKnechtel, obwohl sie subtil unterschiedlich sind. Ihre Version gibt immer etwas aus , entweder Wahr oder Falsch. Meins gibt nur ein einziges True aus. Ich habe keine Ahnung, wie diese Benchmarks aussehen oder ob es genug Unterschiede gibt, um überhaupt eine Rolle zu spielen.
Kirk Strauser
In beiden Fällen anyerhält ein Generator; Es wird nirgendwo eine Liste mit wahren oder falschen Werten erstellt. Meine Version gibt mehr Dinge zurück any, die überprüft werden sollen, aber im Gegenzug, wenn nicht die gleiche Prüfung im Generator selbst durchgeführt wird. Ich stelle mir vor, es ist eine Wäsche, aber hier timeitist es maßgeblich, nicht ich. :)
Karl Knechtel
3

Sie können auch zwei Listen (z. B. a, b) mit dem Operator '+' kombinieren. Beispielsweise,

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

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

Um die vorherigen Antworten noch einmal zusammenzufassen. Wenn Sie eine Liste mit [0,1,2]und eine andere mit haben [3,4,5]und diese zusammenführen möchten [0,1,2,3,4,5], können Sie die Unterschiede entweder verwenden chainingoder extendingsollten sie kennen, um sie mit Bedacht für Ihre Anforderungen zu verwenden.

Liste erweitern

Mit der listKlassenmethode extendkönnen Sie eine Kopie der Elemente von einer Liste in eine andere erstellen. Dies führt jedoch zu einer zusätzlichen Speichernutzung, die in den meisten Fällen in Ordnung sein sollte, jedoch Probleme verursachen kann, wenn Sie speichereffizient sein möchten.

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

Geben Sie hier die Bildbeschreibung ein

Eine Liste verketten

Im Gegensatz dazu können Sie itertools.chainviele Listen verkabeln, wodurch eine so genannte Liste zurückgegeben wird, mit der iteratordie Listen durchlaufen werden können. Dies ist speichereffizienter, da keine Elemente kopiert werden, sondern nur auf die nächste Liste verwiesen wird.

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

Geben Sie hier die Bildbeschreibung ein

Erstellen Sie einen Iterator, der Elemente von der ersten Iterierbarkeit bis zur Erschöpfung zurückgibt und dann zur nächsten Iterierbarkeit übergeht, bis alle Iterabilitäten erschöpft sind. Wird verwendet, um aufeinanderfolgende Sequenzen als einzelne Sequenz zu behandeln.

user1767754
quelle
2

Verwenden der map()und reduce()integrierten Funktionen

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)

Minimales "for looping" und elegantes Codierungsmuster :)

pX0r
quelle
0

Wenn wir eine Liste wie unten haben:

list  = [2,2,3,4]

zwei Möglichkeiten, es in eine andere Liste zu kopieren.

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
Avinash
quelle