Di Python, apa arti dict.pop (a, b)?

92
class a(object):
    data={'a':'aaa','b':'bbb','c':'ccc'}
    def pop(self, key, *args):
            return self.data.pop(key, *args)#what is this mean.

b=a()
print b.pop('a',{'b':'bbb'})
print b.data

self.data.pop(key, *args) ← ------ mengapa ada argumen kedua?

zjm1126
sumber
8
Atau jika Anda benar-benar malas help(b.data.pop)di REPL.
Michael Mior

Jawaban:

121

The popmetode dicts (seperti self.data, yaitu {'a':'aaa','b':'bbb','c':'ccc'}, di sini) membutuhkan dua argumen - lihat dokumentasi

Argumen kedua default,, adalah apa yang popdikembalikan jika argumen pertama key,, tidak ada. (Jika Anda memanggil pophanya dengan satu argumen key,, ini menimbulkan pengecualian jika kunci itu tidak ada).

Dalam contoh Anda print b.pop('a',{'b':'bbb'}), ini tidak relevan karena 'a' merupakan kuncinya b.data. Tetapi jika Anda mengulangi baris itu ...:

b=a()
print b.pop('a',{'b':'bbb'})
print b.pop('a',{'b':'bbb'})
print b.data

Anda akan melihat hal itu membuat perbedaan: pertama popmenghilangkan 'a'kunci, sehingga di kedua poptersebut defaultargumen benar-benar kembali (karena 'a'sekarang absen dari b.data).

Alex Martelli
sumber
3
Hanya sebuah komentar kecil yang menurut saya penting dalam beberapa situasi di mana pengguna membutuhkan popelemen dicttetapi tetap mempertahankan nilai elemen yang muncul. Jadi, dict.pop(key)menghapus keybersama - sama dengan yang terkait valuetetapi juga mengembalikan valuedari keyyang baru saja dihapus. Saya merasa berguna ...
flamenco
@flamenco itulah yang saya harapkan dari pop()- perilaku umum di lebih banyak bahasa seperti JavaScript, PHP, Java, meskipun tidak semua bahasa melakukannya - misalnya C ++.
jave.web
27

Begitu banyak pertanyaan di sini. Saya melihat setidaknya dua, mungkin tiga:

  • Apa yang dilakukan pop (a, b)? / Mengapa ada argumen kedua?
  • Untuk apa *argsdigunakan?

Pertanyaan pertama dijawab dengan mudah dalam referensi Python Standard Library :

pop (kunci [, default])

Jika kunci ada dalam kamus, hapus dan kembalikan nilainya, jika tidak kembalikan default. Jika default tidak diberikan dan key tidak ada dalam kamus, KeyError akan dimunculkan.


Pertanyaan kedua tercakup dalam Referensi Bahasa Python :

Jika bentuk "* pengenal" ada, ini diinisialisasi ke tupel yang menerima parameter posisi berlebih, default ke tupel kosong. Jika formulir "** pengenal" ada, ini diinisialisasi ke kamus baru yang menerima argumen kata kunci berlebih, default ke kamus kosong baru.

Dengan kata lain, popfungsi tersebut membutuhkan setidaknya dua argumen. Dua yang pertama diberi nama selfdan key; dan sisanya dimasukkan ke dalam tupel yang disebut args.

Apa yang terjadi di baris berikutnya ketika *argsditeruskan dalam panggilan ke self.data.popadalah kebalikan dari ini - tupel *argsdiperluas ke parameter posisi yang diteruskan. Ini dijelaskan dalam Referensi Bahasa Python :

Jika ekspresi sintaks * muncul dalam pemanggilan fungsi, ekspresi harus mengevaluasi ke sebuah urutan. Elemen dari urutan ini diperlakukan seolah-olah merupakan argumen posisi tambahan

Singkatnya, a.pop()ingin fleksibel dan menerima sejumlah parameter posisi, sehingga dapat meneruskan sejumlah parameter posisi yang tidak diketahui ini ke self.data.pop().

Ini memberi Anda fleksibilitas; datakebetulan menjadi a dictsekarang, dan dengan demikian self.data.pop()mengambil salah satu atau dua parameter; tetapi jika Anda berubah datamenjadi tipe yang mengambil 19 parameter untuk panggilan, self.data.pop()Anda tidak perlu mengubah kelas asama sekali. Anda masih harus mengubah kode apa pun yang dipanggil a.pop()untuk melewati 19 parameter yang diperlukan.

James Polley
sumber
2
1 untuk usaha. Saya khawatir bahasa Inggris OP tidak sesuai dengan tugas membaca jawaban Anda.
mechanical_meat
Saya menulis itu sebelum saya membaca profil OP. Sekarang saya telah membaca profil tersebut dan melihat beberapa pertanyaan OP lainnya. Saya baru saja mencoba lagi, kali ini hanya menggunakan kode :)
James Polley
7
def func(*args): 
    pass

Saat Anda mendefinisikan fungsi dengan cara ini, *argsakan ada larik argumen yang diteruskan ke fungsi tersebut. Ini memungkinkan fungsi Anda bekerja tanpa mengetahui sebelumnya berapa banyak argumen yang akan diteruskan ke sana.

Anda melakukan ini dengan argumen kata kunci juga, menggunakan **kwargs:

def func2(**kwargs): 
    pass

Lihat: Daftar argumen arbitrer


Dalam kasus Anda, Anda telah menentukan kelas yang bertindak seperti kamus. The dict.popMetode didefinisikan sebagai pop(key[, default]).

Metode Anda tidak menggunakan defaultparameter. Namun, dengan mendefinisikan metode Anda dengan *argsdan meneruskan *argske dict.pop(), Anda mengizinkan pemanggil untuk menggunakan defaultparameter.

Dengan kata lain, Anda harus bisa menggunakan popmetode kelas Anda seperti dict.pop:

my_a = a()
value1 = my_a.pop('key1')       # throw an exception if key1 isn't in the dict
value2 = my_a.pop('key2', None) # return None if key2 isn't in the dict
Seth
sumber
6
>>> def func(a, *args, **kwargs):
...   print 'a %s, args %s, kwargs %s' % (a, args, kwargs)
... 
>>> func('one', 'two', 'three', four='four', five='five')
a one, args ('two', 'three'), kwargs {'four': 'four', 'five': 'five'}

>>> def anotherfunct(beta, *args):
...   print 'beta %s, args %s' % (beta, args)
... 
>>> def func(a, *args, **kwargs):
...   anotherfunct(a, *args)
... 
>>> func('one', 'two', 'three', four='four', five='five')
beta one, args ('two', 'three')
>>> 
James Polley
sumber
1
Saya membaca beberapa pertanyaan, seperti yang dijelaskan dalam jawaban saya yang lain. Saya juga membaca profil OP dan menyadari bahwa jawaban saya yang lain tidak berguna. Jawaban ini harus menunjukkan setidaknya sebagian dari apa yang * args lakukan, yang saya duga kebingungan sebenarnya OP, terlepas dari subjeknya.
James Polley
@ James, +1 untuk usaha ekstra. Saya telah mencapai kesimpulan yang sama tentang pertanyaan sebenarnya.
Peter Hansen