Jak mogę uzyskać produkt kartezjański (każdą możliwą kombinację wartości) z grupy list?
Wejście:
somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]
Pożądane wyjście:
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]
set(cartesian product)
set(inputlist)
wszystkich list wprowadzania. Nie na wyniku.Odpowiedzi:
itertools.product
Dostępne z Python 2.6.
Który jest taki sam jak
źródło
product()
generujenitems_in_a_list ** nlists
elementy w wyniku (reduce(mul, map(len, somelists))
). Nie ma powodu, aby sądzić, że uzyskanie pojedynczego elementu nie jestO(nlists)
(amortyzowane), tj. Złożoność czasowa jest taka sama jak w przypadku prostych zagnieżdżonychfor
pętli, np. Dla danych wejściowych w pytaniu :,nlists=3
całkowita liczba elementów w wyniku:3*2*2
i każdy element manlists
elementy (3
w tym przypadku).*
przed somelistami? Co to robi?źródło
W przypadku Python 2.5 i starszych:
Oto rekurencyjna wersja
product()
(tylko ilustracja):Przykład:
źródło
args
są iteratorami.z itertools.product :
źródło
*
przed somelistami?Użyłbym zrozumienia listy:
źródło
Oto rekurencyjny generator, który nie przechowuje żadnych tymczasowych list
Wynik:
źródło
def f(): while True: yield 1
jak my, będzie ciągle zwiększał swój rozmiar stosu, gdy go przejdziemy?W Pythonie 2.6 i nowszych możesz użyć „itertools.product”. W starszych wersjach Pythona możesz użyć następującego (prawie - patrz dokumentacja) równoważnego kodu z dokumentacji , przynajmniej jako punkt wyjścia:
Wynikiem obu jest iterator, więc jeśli naprawdę potrzebujesz listy do dalszego przetwarzania, użyj
list(result)
.źródło
Chociaż jest już wiele odpowiedzi, chciałbym podzielić się kilkoma przemyśleniami:
Podejście iteracyjne
Podejście rekurencyjne
Podejście Lambda
źródło
Podejście rekurencyjne:
Podejście iteracyjne:
źródło
Niewielka modyfikacja powyższego generatora rekurencyjnego w wariancie smakowym:
I oczywiście opakowanie, dzięki któremu działa dokładnie tak samo jak to rozwiązanie:
z jednym kompromisem : sprawdza, czy rekurencja powinna przerwać się przy każdej zewnętrznej pętli, i jeden zysk : brak dochodu przy pustym wywołaniu, np.
product(())
co, jak sądzę, byłoby semantycznie bardziej poprawne (patrz doctest).Odnośnie rozumienia listy: definicja matematyczna ma zastosowanie do dowolnej liczby argumentów, podczas gdy rozumienie listy może dotyczyć tylko znanej ich liczby.
źródło
Wystarczy dodać trochę do tego, co już powiedziano: jeśli używasz sympy, możesz używać symboli zamiast ciągów znaków, co czyni je matematycznie użytecznymi.
O sympy .
źródło
Wierzę, że to działa:
źródło
Podejście Stonehenge:
wynik:
źródło