Anda juga harus memeriksa **operator - ini melakukan hal yang sama seperti *tetapi dengan argumen kata kunci.
Sean Vieira
Jawaban:
181
* adalah operator "percikan": Ini mengambil daftar sebagai masukan, dan mengembangkannya menjadi argumen posisi aktual dalam pemanggilan fungsi.
Jadi jika uniqueCrossTabsdulu [ [ 1, 2 ], [ 3, 4 ] ], maka itertools.chain(*uniqueCrossTabs)sama saja dengan mengatakanitertools.chain([ 1, 2 ], [ 3, 4 ])
Ini jelas berbeda dengan mengoper uniqueCrossTabs. Dalam kasus Anda, Anda memiliki daftar daftar yang ingin Anda ratakan; apa yang itertools.chain()dilakukan adalah mengembalikan iterator atas rangkaian semua argumen posisi yang Anda berikan padanya, di mana setiap argumen posisi dapat diulang dengan sendirinya.
Dengan kata lain, Anda ingin meneruskan setiap daftar uniqueCrossTabssebagai argumen chain(), yang akan menyatukannya, tetapi Anda tidak memiliki daftar dalam variabel terpisah, jadi Anda menggunakan* operator untuk memperluas daftar daftar menjadi beberapa argumen daftar.
Seperti yang ditunjukkan Jochen Ritzel di komentar, chain.from_iterable()lebih cocok untuk operasi ini, karena mengasumsikan satu iterable untuk memulai. Kode Anda kemudian menjadi:
@larsmans: Saya pikir istilah ini lebih populer di dunia Ruby, tetapi tampaknya juga dapat diterima untuk Python. Saya suka karena menyenangkan untuk mengatakannya ;-)
Cameron
1
@larsmans: Menarik! Saya selalu berpikir ini merujuk pada tindakan membongkar daftar menjadi daftar argumen, bukan karakter sebenarnya.
Cameron
1
Mungkin string bukan contoh terbaik karena tidak semua orang melihat string sebagai iterable. Btw: Daripada chain(*it)saya menulis chain.from_iterable(it).
Jochen Ritzel
@Jochen: Anda benar, saya akan mengubahnya untuk menggunakan angka sebagai gantinya. Juga, saya bahkan tidak tahu from_iterableada! Saya akan segera menambahkannya ke jawaban saya
Cameron
1
@Ramy: *hanya untuk meledakkan daftar menjadi argumen posisi ke suatu fungsi (jadi ya, sangat spesifik). Anda dapat melakukannya for l in uniqueCrossTabs:untuk mengulanginya. Sayangnya sulit untuk melihat *di tempat kerja karena ini hanya berfungsi ketika Anda meneruskan daftar ke suatu fungsi (alih-alih meneruskan daftar sebagai parameter pertama, *menyebabkan setiap elemen dalam daftar diteruskan sebagai parameter terpisah, satu demi satu , seolah-olah telah diketik dipisahkan dengan koma dalam daftar parameter)
Cameron
72
Ini membagi urutan menjadi argumen terpisah untuk pemanggilan fungsi.
>>>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)
Jawaban ini tidak berlaku untuk pertanyaan secara khusus, tetapi merupakan aplikasi penting dari tanda bintang (jadi menurut saya cocok dengan judul yang agak "kabur"). Sejalan dengan itu, aplikasi penting lainnya ada dalam definisi fungsi: def func(a, b, *args):Lihat jawaban ini untuk info lebih lanjut.
**
operator - ini melakukan hal yang sama seperti*
tetapi dengan argumen kata kunci.Jawaban:
*
adalah operator "percikan": Ini mengambil daftar sebagai masukan, dan mengembangkannya menjadi argumen posisi aktual dalam pemanggilan fungsi.Jadi jika
uniqueCrossTabs
dulu[ [ 1, 2 ], [ 3, 4 ] ]
, makaitertools.chain(*uniqueCrossTabs)
sama saja dengan mengatakanitertools.chain([ 1, 2 ], [ 3, 4 ])
Ini jelas berbeda dengan mengoper
uniqueCrossTabs
. Dalam kasus Anda, Anda memiliki daftar daftar yang ingin Anda ratakan; apa yangitertools.chain()
dilakukan adalah mengembalikan iterator atas rangkaian semua argumen posisi yang Anda berikan padanya, di mana setiap argumen posisi dapat diulang dengan sendirinya.Dengan kata lain, Anda ingin meneruskan setiap daftar
uniqueCrossTabs
sebagai argumenchain()
, yang akan menyatukannya, tetapi Anda tidak memiliki daftar dalam variabel terpisah, jadi Anda menggunakan*
operator untuk memperluas daftar daftar menjadi beberapa argumen daftar.Seperti yang ditunjukkan Jochen Ritzel di komentar,
chain.from_iterable()
lebih cocok untuk operasi ini, karena mengasumsikan satu iterable untuk memulai. Kode Anda kemudian menjadi:sumber
chain(*it)
saya menulischain.from_iterable(it)
.from_iterable
ada! Saya akan segera menambahkannya ke jawaban saya*
hanya untuk meledakkan daftar menjadi argumen posisi ke suatu fungsi (jadi ya, sangat spesifik). Anda dapat melakukannyafor l in uniqueCrossTabs:
untuk mengulanginya. Sayangnya sulit untuk melihat*
di tempat kerja karena ini hanya berfungsi ketika Anda meneruskan daftar ke suatu fungsi (alih-alih meneruskan daftar sebagai parameter pertama,*
menyebabkan setiap elemen dalam daftar diteruskan sebagai parameter terpisah, satu demi satu , seolah-olah telah diketik dipisahkan dengan koma dalam daftar parameter)Ini membagi urutan menjadi argumen terpisah untuk pemanggilan fungsi.
sumber
Hanya cara alternatif untuk menjelaskan konsep / menggunakannya.
sumber
def func(a, b, *args):
Lihat jawaban ini untuk info lebih lanjut.