394 Stimmen

Alle Kombinationen aus einer Liste von Listen

Ich bin grundsätzlich auf der Suche nach einer Python-Version von Kombination von List<List<int>>

Ausgehend von einer Liste von Listen benötige ich eine neue Liste, die alle möglichen Kombinationen von Elementen zwischen den Listen enthält.

[[1,2,3],[4,5,6],[7,8,9,10]] -> [[1,4,7],[1,4,8],...,[3,6,10]]

Die Anzahl der Listen ist unbekannt, also brauche ich etwas, das für alle Fälle funktioniert. Bonuspunkte für Eleganz!

6voto

rnso Punkte 21809

Hierfür kann man Base Python verwenden. Der Code benötigt eine Funktion, um Listen von Listen zu glätten:

def flatten(B):    # function needed for code below;
    A = []
    for i in B:
        if type(i) == list: A.extend(i)
        else: A.append(i)
    return A

Dann kann man laufen:

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

outlist =[]; templist =[[]]
for sublist in L:
    outlist = templist; templist = [[]]
    for sitem in sublist:
        for oitem in outlist:
            newitem = [oitem]
            if newitem == [[]]: newitem = [sitem]
            else: newitem = [newitem[0], sitem]
            templist.append(flatten(newitem))

outlist = list(filter(lambda x: len(x)==len(L), templist))  # remove some partial lists that also creep in;
print(outlist)

Sortie :

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

1voto

cellepo Punkte 3302

Dies imitiert meist Lösungen wie Antwort von Jarret Hardie mit itertools.produkt , aber mit diesen Unterschieden:

  • übergibt diese Parameter an itertools.product in-line, statt über eine Variable a - also nein *args Syntax für die Inline-Parameter erforderlich
  • wenn Ihr mypy type-linter sich wie meine verhält, und Sie können Ihren Code dazu bringen, auf andere Weise mit dem *args Syntax mit Inline product Parameter (wie product(*[[1,2,3],[4,5,6],[7,8,9,10]]) ), mypy immer noch scheitern könnte (mit etwas wie error: No overload variant of "product" matches argument type "List[object]" )
  • Die Lösung für dieses Problem mypy ist die Nichtverwendung von *args Syntax, etwa so:

    >>> import itertools
    >>> list(itertools.product([1,2,3],[4,5,6],[7,8,9,10]))
    [(1, 4, 7), (1, 4, 8), (1, 4, 9), (1, 4, 10), (1, 5, 7), (1, 5, 8), (1, 5, 9), (1, 5, 10), (1, 6, 7), (1, 6, 8), (1, 6, 9), (1, 6, 10), (2, 4, 7), (2, 4, 8), (2, 4, 9), (2, 4, 10), (2, 5, 7), (2, 5, 8), (2, 5, 9), (2, 5, 10), (2, 6, 7), (2, 6, 8), (2, 6, 9), (2, 6, 10), (3, 4, 7), (3, 4, 8), (3, 4, 9), (3, 4, 10), (3, 5, 7), (3, 5, 8), (3, 5, 9), (3, 5, 10), (3, 6, 7), (3, 6, 8), (3, 6, 9), (3, 6, 10)]

1voto

Kweku A Punkte 1

Diese Antwort ist nicht so sauber wie die Verwendung von itertools, aber die Ideen könnten nützlich sein.

In Anlehnung an die Konstruktion von zip() aquí könnten wir Folgendes tun.

>>> a = iter([[1,2,3],[4,5,6],[7,8,9,10]])
>>> sentinel = object()
>>> result = [[]]
>>> while True:
>>>     l = next(a,sentinel)
>>>     if l == sentinel:
>>>         break
>>>     result = [ r + [digit] for r in result for digit in l]
>>> print(result)
[[1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 4, 10], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 5, 10], [1, 6, 7], [1, 6, 8], [1, 6, 9], [1, 6, 10], [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 4, 10], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 5, 10], [2, 6, 7], [2, 6, 8], [2, 6, 9], [2, 6, 10], [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 4, 10], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 5, 10], [3, 6, 7], [3, 6, 8], [3, 6, 9], [3, 6, 10]]

Wir verwenden a als Iterator, um sukzessive das nächste Element zu erhalten, ohne von vornherein wissen zu müssen, wie viele es gibt. Die next Der Befehl gibt Folgendes aus sentinel (bei dem es sich um ein Objekt handelt, das ausschließlich für diesen Vergleich erstellt wurde, siehe aquí für einige Erklärungen), wenn wir keine Listen mehr in a , wodurch die if Anweisung auslösen, damit wir aus der Schleife ausbrechen.

-1voto

Kez Punkte 9
from itertools import product 
list_vals = [['Brand Acronym:CBIQ', 'Brand Acronym :KMEFIC'],['Brand Country:DXB','Brand Country:BH']]
list(product(*list_vals))

Sortie :

[('Marken-Akronym:CBIQ', 'Markenland :DXB'),
('Marken-Akronym:CBIQ', 'Markenland:BH'),
('Marken-Akronym :KMEFIC', 'Markenland :DXB'),
('Marken-Akronym :KMEFIC', 'Markenland:BH')]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X