Sie sollten auch den **Operator überprüfen - er funktioniert genauso wie *mit Schlüsselwortargumenten.
Sean Vieira
Antworten:
181
* ist der "splat" -Operator: Er nimmt eine Liste als Eingabe und erweitert sie im Funktionsaufruf zu tatsächlichen Positionsargumenten.
Also wenn uniqueCrossTabsja [ [ 1, 2 ], [ 3, 4 ] ], dannitertools.chain(*uniqueCrossTabs) ist das dasselbe wie zu sagenitertools.chain([ 1, 2 ], [ 3, 4 ])
Dies unterscheidet sich offensichtlich von der gerechten Übergabe uniqueCrossTabs. In Ihrem Fall haben Sie eine Liste von Listen, die Sie reduzieren möchten. Wasitertools.chain() geben einen Iterator über die Verkettung aller Positionsargumente zurück, die Sie an ihn übergeben, wobei jedes Positionsargument für sich iterierbar ist.
Mit anderen Worten, Sie möchten jede Liste uniqueCrossTabsals Argument übergeben chain(), das sie miteinander verkettet, aber Sie haben die Listen nicht in separaten Variablen, also verwenden Sie die* Operator, um die Liste der Listen in mehrere Listenargumente zu erweitern.
Wie Jochen Ritzel in den Kommentaren ausgeführt hat, chain.from_iterable()ist es für diese Operation besser geeignet, da zunächst eine einzige Iterable von Iterablen angenommen wird. Ihr Code wird dann einfach:
@larsmans: Ich denke, der Begriff ist in der Ruby-Welt populärer, aber er scheint auch für Python akzeptabel zu sein. Ich mag ihn, weil es Spaß macht zu sagen ;-)
Cameron
1
@larsmans: Interessant! Ich dachte immer, es beziehe sich auf das Auspacken der Liste in eine Argumentliste, nicht auf das eigentliche Zeichen.
Cameron
1
Vielleicht sind Strings nicht das beste Beispiel, weil nicht jeder Strings als iterable ansieht. Übrigens: Anstatt zu chain(*it)schreiben chain.from_iterable(it).
Jochen Ritzel
@Jochen: Du hast absolut Recht, ich werde es ändern, um stattdessen Zahlen zu verwenden. Außerdem wusste ich nicht einmal, dass es from_iterableexistiert! Ich werde es in Kürze in meine Antwort aufnehmen
Cameron
1
@Ramy: *dient nur zum Auflösen der Liste in Positionsargumente für eine Funktion (also ja, sehr spezifisch). Sie können tun for l in uniqueCrossTabs:, um über sie zu iterieren. Leider ist es *bei der Arbeit schwer zu erkennen , da es nur funktioniert, wenn Sie eine Liste an eine Funktion übergeben (anstatt die Liste als ersten Parameter zu übergeben, *wird jedes Element in der Liste nacheinander als separater Parameter übergeben , als ob sie in der Parameterliste durch Kommas getrennt abgetippt worden wären)
Cameron
72
Es teilt die Sequenz in separate Argumente für den Funktionsaufruf auf.
>>>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)
Dies ist wichtig und wird an keiner anderen Stelle erwähnt
Gershom
1
Diese Antwort bezieht sich nicht speziell auf die Frage, sondern ist eine wichtige Anwendung des Sternchens (daher halte ich es unter dem eher "nebligen" Titel für angemessen). Aus dem gleichen Grund gibt es eine weitere wichtige Anwendung in Funktionsdefinitionen: Weitere Informationen finden def func(a, b, *args):Sie in dieser Antwort .
**
Operator überprüfen - er funktioniert genauso wie*
mit Schlüsselwortargumenten.Antworten:
*
ist der "splat" -Operator: Er nimmt eine Liste als Eingabe und erweitert sie im Funktionsaufruf zu tatsächlichen Positionsargumenten.Also wenn
uniqueCrossTabs
ja[ [ 1, 2 ], [ 3, 4 ] ]
, dannitertools.chain(*uniqueCrossTabs)
ist das dasselbe wie zu sagenitertools.chain([ 1, 2 ], [ 3, 4 ])
Dies unterscheidet sich offensichtlich von der gerechten Übergabe
uniqueCrossTabs
. In Ihrem Fall haben Sie eine Liste von Listen, die Sie reduzieren möchten. Wasitertools.chain()
geben einen Iterator über die Verkettung aller Positionsargumente zurück, die Sie an ihn übergeben, wobei jedes Positionsargument für sich iterierbar ist.Mit anderen Worten, Sie möchten jede Liste
uniqueCrossTabs
als Argument übergebenchain()
, das sie miteinander verkettet, aber Sie haben die Listen nicht in separaten Variablen, also verwenden Sie die*
Operator, um die Liste der Listen in mehrere Listenargumente zu erweitern.Wie Jochen Ritzel in den Kommentaren ausgeführt hat,
chain.from_iterable()
ist es für diese Operation besser geeignet, da zunächst eine einzige Iterable von Iterablen angenommen wird. Ihr Code wird dann einfach:quelle
chain(*it)
schreibenchain.from_iterable(it)
.from_iterable
existiert! Ich werde es in Kürze in meine Antwort aufnehmen*
dient nur zum Auflösen der Liste in Positionsargumente für eine Funktion (also ja, sehr spezifisch). Sie können tunfor l in uniqueCrossTabs:
, um über sie zu iterieren. Leider ist es*
bei der Arbeit schwer zu erkennen , da es nur funktioniert, wenn Sie eine Liste an eine Funktion übergeben (anstatt die Liste als ersten Parameter zu übergeben,*
wird jedes Element in der Liste nacheinander als separater Parameter übergeben , als ob sie in der Parameterliste durch Kommas getrennt abgetippt worden wären)Es teilt die Sequenz in separate Argumente für den Funktionsaufruf auf.
quelle
Nur eine alternative Art, das Konzept zu erklären / zu verwenden.
quelle
def func(a, b, *args):
Sie in dieser Antwort .