einfügen - Wie verkette ich zwei Listen in Python?




subtrahieren addieren (21)

Sie können Sets verwenden, um eine zusammengeführte Liste eindeutiger Werte zu erhalten

mergedlist = list(set(listone + listtwo))

Wie verknüpfe ich zwei Listen in Python?

Beispiel:

listone = [1, 2, 3]
listtwo = [4, 5, 6]

Erwartetes Ergebnis:

>>> joinedlist
[1, 2, 3, 4, 5, 6]

Es ist auch möglich, einen Generator zu erstellen, der einfach über die Elemente in beiden Listen iteriert. Dadurch können Sie Listen (oder beliebige iterierbare) für die Verarbeitung aneinanderreihen, ohne die Elemente in eine neue Liste zu kopieren:

import itertools
for item in itertools.chain(listone, listtwo):
   # do something with each list item

Wenn Sie eine neue Liste wünschen, während Sie die zwei alten Listen behalten:

joinedList = []
for i in listOne:
    joinedList.append(i)
for j in listTwo:
    joinedList.append(j)

sorted(joinedList)

return joinedList

import itertools

A = list(zip([1,3,5,7,9],[2,4,6,8,10]))
B = [1,3,5,7,9]+[2,4,6,8,10]
C = list(set([1,3,5,7,9] + [2,4,6,8,10]))

D = [1,3,5,7,9]
D.append([2,4,6,8,10])

E = [1,3,5,7,9]
E.extend([2,4,6,8,10])

F = []
for a in itertools.chain([1,3,5,7,9], [2,4,6,8,10]):
    F.append(a)


print ("A: " + str(A))
print ("B: " + str(B))
print ("C: " + str(C))
print ("D: " + str(D))
print ("E: " + str(E))
print ("F: " + str(F))

Ausgabe:

A: [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
B: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
C: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
D: [1, 3, 5, 7, 9, [2, 4, 6, 8, 10]]
E: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
F: [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]

Fügen Sie zwei Listen in Python hinzu:

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

Wenn Sie keine Duplizierung wünschen:

>>> a = [1, 2, 3, 4, 5, 6]
>>> b = [5, 6, 7, 8]
>>> c = list(set(a + b))
>>> c
[1, 2, 3, 4, 5, 6, 7, 8]

Sie können den Operator + , um sie zu kombinieren:

listone = [1,2,3]
listtwo = [4,5,6]

mergedlist = listone + listtwo

Ausgabe:

>>> mergedlist
[1,2,3,4,5,6]

Sie können auch extend verwenden, um eine list hinzuzufügen, indem Sie das Ende eines anderen hinzufügen:

listone = [1,2,3]
listtwo = [4,5,6]
mergedlist = []
mergedlist.extend(listone)
mergedlist.extend(listtwo)

Python >= 3.5 Alternative: [*l1, *l2]

Obwohl dies eine alte Antwort ist, wurde durch die Annahme von PEP 448 eine weitere Alternative eingeführt, die Erwähnung verdient.

Die PEP mit dem Titel Zusätzliche Entpackungs-Generalisierungen reduzierte im Allgemeinen einige syntaktische Einschränkungen, wenn der Stern * in Python verwendet wurde. damit können zwei Listen (gilt für jedes iterable) nun auch mit

>>> l1 = [1, 2, 3]
>>> l2 = [4, 5, 6]

#unpack both iterables in a list literal
>>> joinedList = [*l1, *l2]
>>> print(joinedList)
[1, 2, 3, 4, 5, 6]

Diese Funktionalität wurde für Python 3.5 definiert und wurde nicht auf frühere Versionen in der 3.x Familie 3.x . In nicht unterstützten Versionen wird ein SyntaxError .

Wie bei den anderen Ansätzen erzeugt auch dies eine flache Kopie der Elemente in den entsprechenden Listen.

Der Vorteil dieses Ansatzes besteht darin, dass Sie wirklich keine Listen benötigen, um sie auszuführen, alles, was iterierbar ist, wird ausreichen. Wie in der PEP angegeben:

Dies ist auch nützlich als eine besser lesbare Möglichkeit zum my_list + list(my_tuple) + list(my_range) in eine Liste, wie beispielsweise my_list + list(my_tuple) + list(my_range) was nun nur [*my_list, *my_tuple, *my_range] .

Während also die Addition mit + einen TypeError wegen Typ-Mismatch TypeError würde:

l = [1, 2, 3]
r = range(4, 7)
res = l + r

Das Folgende wird nicht:

res = [*l, *r]

weil es zuerst den Inhalt der Iterablen entpackt und dann einfach eine list aus dem Inhalt erstellt.


Diese Frage fragt direkt nach dem Beitritt zu zwei Listen. Es ist jedoch ziemlich hoch in der Suche, auch wenn Sie nach einer Möglichkeit suchen, vielen Listen beizutreten (einschließlich des Falls, wenn Sie Nulllisten beitreten). Betrachten Sie diesen allgemeineren Ansatz:

a = [[1,2,3], [4,5,6], [7,8,9]]
reduce(lambda c, x: c + x, a, [])

Wird ausgegeben:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Beachten Sie, dass dies auch korrekt funktioniert, wenn a [] oder [[1,2,3]] .

Dies kann jedoch mit itertools effizienter itertools :

a = [[1,2,3], [4,5,6], [7,8,9]]
list(itertools.chain(*a))

Wenn Sie keine list benötigen, sondern nur eine iterierbare list() , lassen Sie sie weg.

Aktualisieren

Alternative von Patrick Collins in den Kommentaren vorgeschlagen könnte auch für Sie arbeiten:

sum(a, [])

Wenn Sie die beiden Listen in sortierter Form zusammenführen möchten, können Sie die Zusammenführungsfunktion aus der heapq-Bibliothek verwenden.

from heapq import merge

a = [1,2,4]
b = [2,4,6,7]

print list(merge(a,b))

list(set(listone) | set(listtwo))

Der obige Code behält die Reihenfolge nicht bei, entfernt Duplikate aus jeder Liste (aber nicht aus der verketteten Liste)


Als allgemeinere Möglichkeit für weitere Listen können Sie sie in eine Liste itertools.chain.from_iterable() und itertools.chain.from_iterable() 1 Funktion, die basierend auf dieser Antwort die beste Möglichkeit ist, eine verschachtelte Liste zu glätten:

>>> l=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import itertools
>>> list(itertools.chain.from_iterable(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9] 

1. Beachten Sie, dass chain.from_iterable() in python => 2.6 verfügbar ist. In anderen Versionen verwenden Sie chain(*l)


Sie könnten die für append() definierte append() -Methode verwenden:

mergedlist =[]
for elem in listone:
    mergedlist.append(elem)
for elem in listtwo:
    mergedlist.append(elem)

Wenn Sie zwei geordnete Listen mit komplizierten Sortierungsregeln zusammenführen müssen, müssen Sie sie möglicherweise wie im folgenden Code selbst rollen (mit einer einfachen Sortierregel für Lesbarkeit :-)).

list1 = [1,2,5]
list2 = [2,3,4]
newlist = []

while list1 and list2:
    if list1[0] == list2[0]:
        newlist.append(list1.pop(0))
        list2.pop(0)
    elif list1[0] < list2[0]:
        newlist.append(list1.pop(0))
    else:
        newlist.append(list2.pop(0))

if list1:
    newlist.extend(list1)
if list2:
    newlist.extend(list2)

assert(newlist == [1, 2, 3, 4, 5])

Sie können für extend gehen.

l1 = [1,2,3]
l2 = [4,5,6]
l1.extend(l2)
print l1

Ausgabe: [1,2,3,4,5,6]


Wenn Sie den __add__ ( + ) nicht verwenden können, können Sie die Funktion __add__ verwenden:

listone = [1,2,3]
listtwo = [4,5,6]

result = list.__add__(listone, listtwo)
print(result)

>>> [1, 2, 3, 4, 5, 6]

Wenn Sie die Verwendung von dunders gern nicht mögen, dunders Sie dunders den operator import verwenden:

import operator

listone = [1,2,3]
listtwo = [4,5,6]

result = operator.add(listone, listtwo)
print(result)

>>> [1, 2, 3, 4, 5, 6]

Man könnte argumentieren, dass dies etwas lesbarer ist.


Mit Python 3.3+ können Sie Ertrag von :

listone = [1,2,3]
listtwo = [4,5,6]

def merge(l1, l2):
    yield from l1
    yield from l2

>>> list(merge(listone, listtwo))
[1, 2, 3, 4, 5, 6]

Oder wenn Sie eine beliebige Anzahl von Iteratoren unterstützen wollen:

def merge(*iters):
    for it in iters:
        yield from it

>>> list(merge(listone, listtwo, 'abcd', [20, 21, 22]))
[1, 2, 3, 4, 5, 6, 'a', 'b', 'c', 'd', 20, 21, 22]

Das ist ziemlich einfach, ich denke, es wurde sogar im tutorial :

>>> listone = [1,2,3]
>>> listtwo = [4,5,6]
>>>
>>> listone + listtwo
[1, 2, 3, 4, 5, 6]

Wie bereits von vielen gezeigt, ist itertools.chain() der itertools.chain() Weg, wenn man genau dieselbe Behandlung auf beide Listen anwenden muss. In meinem Fall hatte ich ein Label und eine Flagge, die sich von einer Liste zur anderen unterschieden, also brauchte ich etwas etwas Komplexeres. Wie sich herausstellt, tut itertools.chain() hinter den Kulissen einfach folgendes:

for it in iterables:
    for element in it:
        yield element

(siehe https://docs.python.org/2/library/itertools.html ), also habe ich mich von hier inspirieren lassen und etwas in diese Richtung geschrieben:

for iterable, header, flag in ( (newList, 'New', ''), (modList, 'Modified', '-f')):
    print header + ':'
    for path in iterable:
        [...]
        command = 'cp -r' if os.path.isdir(srcPath) else 'cp'
        print >> SCRIPT , command, flag, srcPath, mergedDirPath
        [...]

Die wichtigsten Punkte, die hier zu verstehen sind, sind, dass Listen nur ein Spezialfall von iterierbar sind, also Objekte wie jedes andere; und dass for ... in Schleifen in Python mit Tuple-Variablen arbeiten kann, ist es einfach, mehrere Variablen gleichzeitig zu durchlaufen.


Sie können einfach den Operator + oder += wie folgt verwenden:

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

c = a + b

Oder:

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

c += (a + b)

Wenn Sie möchten, dass die Werte in der zusammengeführten Liste eindeutig sind, können Sie Folgendes tun:

c = list(set(a + b))

Um zu verstehen, was yield bringt, müssen Sie verstehen, was Generatoren sind. Und vor Generatoren kommen Iterables .

Iterables

Wenn Sie eine Liste erstellen, können Sie deren Elemente einzeln lesen. Das Lesen der Elemente nacheinander wird als Iteration bezeichnet:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

mylist ist eine iterable . Wenn Sie ein Listenverständnis verwenden, erstellen Sie eine Liste und damit eine Iteration:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

Alles, was Sie " for... in... " verwenden können, ist ein iterierbares Element. lists , strings , Dateien ...

Diese iterablen Funktionen sind praktisch, weil Sie sie so oft lesen können, wie Sie möchten, aber Sie speichern alle Werte im Speicher und dies ist nicht immer das, was Sie wollen, wenn Sie viele Werte haben.

Generatoren

Generatoren sind Iteratoren, eine Art Iterer, den Sie nur einmal durchlaufen können . Generatoren speichern nicht alle Werte im Speicher, sie generieren die Werte im laufenden Betrieb :

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4

Es ist genau dasselbe, außer dass Sie () anstelle von [] . ABER, Sie können for i in mygenerator kein zweites Mal durchführen, da Generatoren nur einmal verwendet werden können: Sie berechnen 0, vergessen sie dann und berechnen 1, und beenden 4 nacheinander.

Ausbeute

yield ist ein Schlüsselwort, das wie return , außer dass die Funktion einen Generator zurückgibt.

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4

Dies ist ein unbrauchbares Beispiel, aber es ist praktisch, wenn Sie wissen, dass Ihre Funktion eine riesige Menge von Werten zurückgibt, die Sie nur einmal lesen müssen.

Um den yield zu beherrschen, müssen Sie verstehen, dass der Code, den Sie in den Funktionshauptteil geschrieben haben , beim Aufruf der Funktion nicht ausgeführt wird. Die Funktion gibt nur das Generatorobjekt zurück, das ist etwas knifflig :-)

Dann wird Ihr Code jedes Mal ausgeführt, wenn der Generator den Generator verwendet.

Nun der schwierige Teil:

Beim ersten Aufruf von for das Generatorobjekt, das von Ihrer Funktion erstellt wurde, wird der Code in Ihrer Funktion vom Anfang bis zum Aufruf von yield . Dann wird der erste Wert der Schleife zurückgegeben. Dann führt jeder andere Aufruf die Schleife, die Sie in die Funktion geschrieben haben, noch einmal aus und gibt den nächsten Wert zurück, bis es keinen Wert gibt, der zurückgegeben werden soll.

Der Generator wird als leer betrachtet, wenn die Funktion ausgeführt wird, trifft jedoch nicht mehr auf den yield . Das kann daran liegen, dass die Schleife zu Ende gegangen ist oder Sie ein "if/else" nicht mehr befriedigen.

Ihr Code erklärt

Generator:

# Here you create the method of the node object that will return the generator
def _get_child_candidates(self, distance, min_dist, max_dist):

    # Here is the code that will be called each time you use the generator object:

    # If there is still a child of the node object on its left
    # AND if distance is ok, return the next child
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild

    # If there is still a child of the node object on its right
    # AND if distance is ok, return the next child
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild

    # If the function arrives here, the generator will be considered empty
    # there is no more than two values: the left and the right children

Anrufer:

# Create an empty list and a list with the current object reference
result, candidates = list(), [self]

# Loop on candidates (they contain only one element at the beginning)
while candidates:

    # Get the last candidate and remove it from the list
    node = candidates.pop()

    # Get the distance between obj and the candidate
    distance = node._get_dist(obj)

    # If distance is ok, then you can fill the result
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)

    # Add the children of the candidate in the candidates list
    # so the loop will keep running until it will have looked
    # at all the children of the children of the children, etc. of the candidate
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))

return result

Dieser Code enthält mehrere intelligente Teile:

  • Die Schleife durchläuft eine Liste, die Liste wird jedoch erweitert, während die Schleife durchlaufen wird :-) Es ist eine prägnante Methode, all diese verschachtelten Daten durchzugehen, auch wenn sie etwas gefährlich ist, da Sie mit einer Endlosschleife enden können. In diesem Fall erschöpft candidates.extend(node._get_child_candidates(distance, min_dist, max_dist)) alle Werte des Generators, erstellt jedoch while neue Generatorobjekte, die andere als die vorherigen generieren, da sie nicht auf dieselben Werte angewendet werden Knoten.

  • Die extend() -Methode ist eine Listenobjektmethode, die eine Iteration erwartet und ihre Werte zur Liste hinzufügt.

Normalerweise übergeben wir eine Liste:

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

Aber in Ihrem Code bekommt es einen Generator, was gut ist, weil:

  1. Sie müssen die Werte nicht zweimal lesen.
  2. Möglicherweise haben Sie viele Kinder und möchten nicht, dass sie alle im Speicher gespeichert werden.

Und es funktioniert, weil Python sich nicht darum kümmert, ob das Argument einer Methode eine Liste ist oder nicht. Python erwartet iterable, also funktioniert es mit Strings, Listen, Tupeln und Generatoren! Dies wird als Duck-Typing bezeichnet und ist einer der Gründe, warum Python so cool ist. Aber das ist eine andere Geschichte, für eine andere Frage ...

Sie können hier anhalten oder ein wenig lesen, um eine erweiterte Verwendung eines Generators zu sehen:

Kontrolle der Generatorerschöpfung

>>> class Bank(): # Let's create a bank, building ATMs
...    crisis = False
...    def create_atm(self):
...        while not self.crisis:
...            yield "$100"
>>> hsbc = Bank() # When everything's ok the ATM gives you as much as you want
>>> corner_street_atm = hsbc.create_atm()
>>> print(corner_street_atm.next())
$100
>>> print(corner_street_atm.next())
$100
>>> print([corner_street_atm.next() for cash in range(5)])
['$100', '$100', '$100', '$100', '$100']
>>> hsbc.crisis = True # Crisis is coming, no more money!
>>> print(corner_street_atm.next())
<type 'exceptions.StopIteration'>
>>> wall_street_atm = hsbc.create_atm() # It's even true for new ATMs
>>> print(wall_street_atm.next())
<type 'exceptions.StopIteration'>
>>> hsbc.crisis = False # The trouble is, even post-crisis the ATM remains empty
>>> print(corner_street_atm.next())
<type 'exceptions.StopIteration'>
>>> brand_new_atm = hsbc.create_atm() # Build a new one to get back in business
>>> for cash in brand_new_atm:
...    print cash
$100
$100
$100
$100
$100
$100
$100
$100
$100
...

Hinweis: Verwenden Sie für Python 3 print(corner_street_atm.__next__()) oder print(next(corner_street_atm))

Dies kann für verschiedene Zwecke nützlich sein, beispielsweise für die Steuerung des Zugriffs auf eine Ressource.

Itertools, dein bester Freund

Das itertools-Modul enthält spezielle Funktionen zur Bearbeitung von Iterationen. Wollten Sie schon immer einen Generator kopieren? Kette zwei Generatoren? Werte in einer verschachtelten Liste mit einem Einzeiler gruppieren? Map / Zip ohne eine andere Liste zu erstellen?

Dann import itertools einfach import itertools .

Ein Beispiel? Lassen Sie uns die möglichen Reihenfolge der Ankunft für ein Vierpferderennen sehen:

>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)
<itertools.permutations object at 0xb754f1dc>
>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
 (1, 2, 4, 3),
 (1, 3, 2, 4),
 (1, 3, 4, 2),
 (1, 4, 2, 3),
 (1, 4, 3, 2),
 (2, 1, 3, 4),
 (2, 1, 4, 3),
 (2, 3, 1, 4),
 (2, 3, 4, 1),
 (2, 4, 1, 3),
 (2, 4, 3, 1),
 (3, 1, 2, 4),
 (3, 1, 4, 2),
 (3, 2, 1, 4),
 (3, 2, 4, 1),
 (3, 4, 1, 2),
 (3, 4, 2, 1),
 (4, 1, 2, 3),
 (4, 1, 3, 2),
 (4, 2, 1, 3),
 (4, 2, 3, 1),
 (4, 3, 1, 2),
 (4, 3, 2, 1)]

Die inneren Mechanismen der Iteration verstehen

Iteration ist ein Prozess, der __iter__() (Implementieren der __iter__() Methode) und Iteratoren (Implementieren der __next__() Methode) __next__() . Iterables sind alle Objekte, von denen Sie einen Iterator erhalten können. Iteratoren sind Objekte, mit denen Sie iterierbare Elemente durchlaufen können.

In diesem Artikel erfahren Sie mehr darüber, wie Schleifen funktionieren .







python list