Pengertian *x ,= lst

I'm akan melalui beberapa kode lama mencoba untuk memahami apa yang dilakukannya, dan saya datang di ini aneh pernyataan:

*x ,= p

p adalah sebuah daftar dalam konteks ini. I've telah mencoba untuk mencari tahu apa pernyataan ini tidak. Sejauh yang saya tahu, itu hanya menetapkan x nilai p. Misalnya:

p = [1,2]
*x ,= p    
print(x)

Hanya memberikan

[1, 2]

Jadi ini berbeda dari x = p? Ide apa sintaks ini lakukan?

Mengomentari pertanyaan (3)
Larutan

*x ,= p pada dasarnya adalah sebuah dikaburkan versi x = list(p) dengan menggunakan extended iterable membongkar. Koma setelah x diperlukan untuk membuat target penempatan sebuah tuple (hal ini juga bisa menjadi daftar meskipun).

*x, = p adalah berbeda dari x = p karena mantan menciptakan copy p (yaitu daftar baru) sedangkan yang kedua menciptakan referensi asli daftar. Untuk menggambarkan:

>>> p = [1, 2]
>>> *x, = p 
>>> x == p
True
>>> x is p
False
>>> x = p
>>> x == p
True
>>> x is p
True
Komentar (3)

It's fitur yang diperkenalkan di Python 3.0 (PEP 3132). Di Python 2, anda bisa melakukan sesuatu seperti ini:

>>> p = [1, 2, 3]
>>> q, r, s = p
>>> q
1
>>> r
2
>>> s
3

Python 3 diperpanjang ini sehingga salah satu variabel yang dapat menyimpan beberapa nilai-nilai:

>>> p = [1, 2, 3]
>>> q, *r = p
>>> q
1
>>> r
[2, 3]

Ini, oleh karena itu, adalah apa yang sedang digunakan di sini. Bukan dua variabel untuk menampung tiga nilai, namun, itu hanya salah satu variabel yang dibutuhkan masing-masing nilai dalam daftar. Ini adalah berbeda dari x = p karena x = p berarti x adalah nama lain untuk p. Dalam kasus ini, bagaimanapun, itu adalah sebuah daftar baru yang hanya terjadi untuk memiliki nilai yang sama di dalamnya. (Anda mungkin akan tertarik https://stackoverflow.com/q/1132941/5827958)

Dua cara umum lainnya yang menghasilkan efek ini adalah:

>>> x = list(p)

dan

>>> x = p[:]

Sejak Python 3.3, daftar objek sebenarnya memiliki metode yang dimaksudkan untuk menyalin:

x = p.copy()

Slice adalah benar-benar sangat mirip konsep. Sebagai nneonneo menunjukkan, bagaimanapun, bahwa hanya bekerja dengan benda-benda seperti list dan tuple yang mendukung irisan. Metode yang anda sebutkan, bagaimanapun, bekerja dengan iterable: kamus, set, generator, dll.

Komentar (5)

Anda harus selalu melemparkan ini ke dis dan melihat apa yang melempar kembali pada anda; anda'll melihat bagaimana *x, = p adalah benar-benar berbeda dari x = p:

dis('*x, = p')
  1           0 LOAD_NAME                0 (p)
              2 UNPACK_EX                0
              4 STORE_NAME               1 (x)

Sementara, sederhana penugasan pernyataan:

dis('x = p')
  1           0 LOAD_NAME                0 (p)
              2 STORE_NAME               1 (x)

(Stripping off terkait None kembali)

Seperti yang anda lihat UNPACK_EX adalah berbeda op-code antara ini; it's didokumentasikan sebagai:

Melaksanakan tugas dengan membintangi target: Membongkar sebuah iterable di TOS (top of stack) ke nilai-nilai individu, dimana jumlah total dari nilai-nilai dapat menjadi lebih kecil dari jumlah item dalam iterable: salah satu nilai-nilai baru yang akan daftar semua barang yang masih tersisa.

Itulah sebabnya, seperti Eugene mencatat, anda mendapatkan sebuah objek baru yang's disebut dengan nama x dan tidak referensi ke objek yang sudah ada (seperti halnya dengan x = p).


*x, tidak tampak sangat aneh (koma ekstra di sana dan semua) tetapi diperlukan di sini. Sisi kiri harus berupa sebuah tuple atau daftar dan, karena quirkiness menciptakan satu elemen tupel pada Python, anda perlu menggunakan akhiran ,:

i = 1, # one element tuple

Jika anda suka membingungkan orang-orang, anda dapat selalu menggunakan daftar versi ini:

[*x] = p

yang tidak persis hal yang sama tapi doesn't memiliki tambahan koma berkeliaran di sana.

Komentar (0)