powinieneś również sprawdzić **operator - robi to samo, *ale z argumentami słów kluczowych.
Sean Vieira
Odpowiedzi:
181
* jest operatorem "splat": Pobiera listę jako dane wejściowe i rozwija ją w rzeczywiste argumenty pozycyjne w wywołaniu funkcji.
Więc jeśli uniqueCrossTabsbyło [ [ 1, 2 ], [ 3, 4 ] ], to itertools.chain(*uniqueCrossTabs)znaczy to samo, co powiedzenieitertools.chain([ 1, 2 ], [ 3, 4 ])
To oczywiście różni się od przekazywania po prostu uniqueCrossTabs. W twoim przypadku masz listę list, które chcesz spłaszczyć; co itertools.chain()robi jest powrót iterator nad połączeniem wszystkich pozycyjnych argumentów przekazać do niej, gdzie każdy argument jest iterable pozycyjny w sobie.
Innymi słowy, chcesz przekazać każdą listę uniqueCrossTabsjako argument chain(), który połączy je w łańcuch, ale nie masz list w osobnych zmiennych, więc używasz *operatora, aby rozszerzyć listę list na kilka argumentów list.
Jak zauważył Jochen Ritzel w komentarzach, chain.from_iterable()jest lepiej dostosowany do tej operacji, ponieważ zakłada na początek jedną iterowalną iterowalność. Twój kod staje się wtedy po prostu:
@larsmans: Myślę, że termin jest bardziej popularny w świecie Rubiego, ale wydaje się, że jest akceptowalny również dla Pythona. Lubię go, bo fajnie to powiedzieć ;-)
Cameron
1
@larsmans: Interesujące! Zawsze myślałem, że odnosi się to do rozpakowywania listy do listy argumentów, a nie do samego znaku.
Cameron
1
Może łańcuchy nie są najlepszym przykładem, ponieważ nie każdy postrzega łańcuchy jako iterowalne. Btw: Zamiast chain(*it)pisać chain.from_iterable(it).
Jochen Ritzel
@Jochen: Masz całkowitą rację, zmienię to, żeby zamiast tego używał liczb. Poza tym nawet nie wiedziałem, że from_iterableistnieje! Wkrótce dodam to do mojej odpowiedzi
Cameron
1
@Ramy: *służy tylko do rozbicia listy na argumenty pozycyjne funkcji (więc tak, bardzo konkretne). Możesz zrobić, for l in uniqueCrossTabs:aby je iterować. Niestety ciężko to zobaczyć *w pracy, ponieważ działa tylko wtedy, gdy przekazujesz listę do funkcji (zamiast przekazywać listę jako pierwszy parametr, *powoduje , że każdy element na liście jest przekazywany jako oddzielny parametr, jeden po drugim , jakby zostały wpisane oddzielone przecinkami w liście parametrów)
Cameron
72
Dzieli sekwencję na oddzielne argumenty dla wywołania funkcji.
>>>def foo(a, b=None, c=None):...print a, b, c
...>>> foo([1,2,3])[1,2,3]NoneNone>>> foo(*[1,2,3])123>>>def bar(*a):...print a
...>>> bar([1,2,3])([1,2,3],)>>> bar(*[1,2,3])(1,2,3)
Ta odpowiedź nie dotyczy konkretnie pytania, ale jest ważnym zastosowaniem gwiazdki (więc myślę, że jest odpowiednia pod raczej „mglistym” tytułem). W tym samym duchu inna ważna aplikacja dotyczy definicji funkcji: def func(a, b, *args):Zobacz tę odpowiedź, aby uzyskać więcej informacji.
**
operator - robi to samo,*
ale z argumentami słów kluczowych.Odpowiedzi:
*
jest operatorem "splat": Pobiera listę jako dane wejściowe i rozwija ją w rzeczywiste argumenty pozycyjne w wywołaniu funkcji.Więc jeśli
uniqueCrossTabs
było[ [ 1, 2 ], [ 3, 4 ] ]
, toitertools.chain(*uniqueCrossTabs)
znaczy to samo, co powiedzenieitertools.chain([ 1, 2 ], [ 3, 4 ])
To oczywiście różni się od przekazywania po prostu
uniqueCrossTabs
. W twoim przypadku masz listę list, które chcesz spłaszczyć; coitertools.chain()
robi jest powrót iterator nad połączeniem wszystkich pozycyjnych argumentów przekazać do niej, gdzie każdy argument jest iterable pozycyjny w sobie.Innymi słowy, chcesz przekazać każdą listę
uniqueCrossTabs
jako argumentchain()
, który połączy je w łańcuch, ale nie masz list w osobnych zmiennych, więc używasz*
operatora, aby rozszerzyć listę list na kilka argumentów list.Jak zauważył Jochen Ritzel w komentarzach,
chain.from_iterable()
jest lepiej dostosowany do tej operacji, ponieważ zakłada na początek jedną iterowalną iterowalność. Twój kod staje się wtedy po prostu:źródło
chain(*it)
pisaćchain.from_iterable(it)
.from_iterable
istnieje! Wkrótce dodam to do mojej odpowiedzi*
służy tylko do rozbicia listy na argumenty pozycyjne funkcji (więc tak, bardzo konkretne). Możesz zrobić,for l in uniqueCrossTabs:
aby je iterować. Niestety ciężko to zobaczyć*
w pracy, ponieważ działa tylko wtedy, gdy przekazujesz listę do funkcji (zamiast przekazywać listę jako pierwszy parametr,*
powoduje , że każdy element na liście jest przekazywany jako oddzielny parametr, jeden po drugim , jakby zostały wpisane oddzielone przecinkami w liście parametrów)Dzieli sekwencję na oddzielne argumenty dla wywołania funkcji.
źródło
Tylko alternatywny sposób wyjaśnienia pojęcia / wykorzystania go.
źródło
def func(a, b, *args):
Zobacz tę odpowiedź, aby uzyskać więcej informacji.