ใน Python 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) ← ------ เหตุใดจึงมีอาร์กิวเมนต์ที่สอง


8
หรือถ้าคุณขี้เกียจhelp(b.data.pop)ใน REPL
Michael Mior

คำตอบ:


121

popวิธีการ dicts (เหมือนself.dataเช่น{'a':'aaa','b':'bbb','c':'ccc'}ที่นี่) ใช้เวลาสองอาร์กิวเมนต์ - ดูเอกสาร

อาร์กิวเมนต์ที่สองdefaultคือสิ่งที่popผลตอบแทนถ้าอาร์กิวเมนต์แรกkeyคือขาด (หากคุณเรียกpopด้วยอาร์กิวเมนต์เดียวkeyจะทำให้เกิดข้อยกเว้นหากไม่มีคีย์นั้น)

ในตัวอย่างของprint b.pop('a',{'b':'bbb'})นี้เป็นที่ไม่เกี่ยวข้องเพราะ'a' เป็นb.dataคีย์ใน แต่ถ้าคุณทำซ้ำบรรทัดนั้น ... :

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

คุณจะเห็นว่ามันทำให้ความแตกต่าง: ครั้งแรกที่popเอา'a'กุญแจสำคัญดังนั้นในครั้งที่สองอาร์กิวเมนต์จะถูกส่งกลับจริง (ตั้งแต่อยู่ในขณะนี้ขาด)popdefault'a'b.data


3
เป็นเพียงความคิดเห็นเล็ก ๆ น้อย ๆ ซึ่งฉันคิดว่ามันมีความสำคัญในบางสถานการณ์ที่ผู้ใช้ต้องการpopองค์ประกอบdictแต่คงไว้ซึ่งคุณค่าขององค์ประกอบที่โผล่ขึ้นมา ดังนั้นdict.pop(key)เอาkeyพร้อมกับการที่เกี่ยวข้องvalueแต่ยังส่งกลับvalueของkeyที่ได้รับเพียงแค่ออก ฉันคิดว่ามันมีประโยชน์ ...
flamenco

@flamenco นั่นคือสิ่งที่ฉันคาดหวังpop()- พฤติกรรมทั่วไปในภาษาอื่น ๆ เช่น JavaScript, PHP, Java แม้ว่าไม่ใช่ทุกภาษาที่ทำเช่นนั้น - เช่น C ++
jave.web

27

คำถามมากมายที่นี่ ฉันเห็นอย่างน้อยสองอย่างอาจจะสาม:

  • ป๊อป (a, b) ทำอะไร / เหตุใดจึงมีอาร์กิวเมนต์ที่สอง
  • อะไรคือสิ่งที่*argsถูกนำมาใช้หรือไม่?

คำถามแรกได้รับคำตอบเล็กน้อยในการอ้างอิงPython Standard Library :

ป๊อป (คีย์ [ค่าเริ่มต้น])

หากคีย์อยู่ในพจนานุกรมให้ลบออกและส่งคืนค่ามิฉะนั้นจะคืนค่าเริ่มต้น หากไม่กำหนดค่าเริ่มต้นและไม่มีคีย์อยู่ในพจนานุกรม KeyError จะเพิ่มขึ้น


คำถามที่สองครอบคลุมในการอ้างอิงภาษา Python :

หากมีรูปแบบ“ * identifier” จะถูกกำหนดค่าเริ่มต้นให้กับทูเปิลที่ได้รับพารามิเตอร์ตำแหน่งส่วนเกินโดยมีค่าเริ่มต้นเป็นทูเพิลว่าง หากมีรูปแบบ“ ** identifier” แสดงว่ามีการเตรียมข้อมูลเบื้องต้นให้กับพจนานุกรมใหม่ที่ได้รับอาร์กิวเมนต์คำหลักที่มากเกินไปโดยมีค่าเริ่มต้นเป็นพจนานุกรมเปล่าใหม่

กล่าวอีกนัยหนึ่งpopฟังก์ชันใช้เวลาอย่างน้อยสองอาร์กิวเมนต์ สองคนแรกได้รับมอบหมายชื่อselfและkey; argsและส่วนที่เหลือจะยัดเข้ามาในอันดับที่เรียกว่า

สิ่งที่เกิดขึ้นในบรรทัดถัดไปเมื่อ*argsถูกส่งต่อไปในการเรียกไปยังself.data.popเป็นสิ่งที่ผกผันของสิ่งนี้ - ทูเพิล*argsจะขยายเป็นพารามิเตอร์ตำแหน่งที่ส่งผ่านไป สิ่งนี้อธิบายไว้ในการอ้างอิงภาษา Python :

หากนิพจน์ไวยากรณ์ * ปรากฏในการเรียกใช้ฟังก์ชันนิพจน์ต้องประเมินเป็นลำดับ องค์ประกอบจากลำดับนี้จะถือว่าเป็นอาร์กิวเมนต์ตำแหน่งเพิ่มเติม

ในระยะสั้นa.pop()อยากจะมีความยืดหยุ่นและยอมรับจำนวนพารามิเตอร์ตำแหน่งใด ๆ self.data.pop()เพื่อที่จะสามารถผ่านนี้ไม่ทราบจำนวนพารามิเตอร์ตำแหน่งไป

สิ่งนี้ช่วยให้คุณมีความยืดหยุ่น dataเกิดขึ้นเป็นdictตอนนี้และself.data.pop()ใช้พารามิเตอร์หนึ่งหรือสองพารามิเตอร์ แต่ถ้าคุณเปลี่ยนdataเป็นประเภทที่ใช้ 19 พารามิเตอร์สำหรับการโทรself.data.pop()คุณจะไม่ต้องเปลี่ยนคลาสaเลย คุณยังคงต้องเปลี่ยนรหัสที่เรียกa.pop()ให้ส่งผ่านพารามิเตอร์ 19 ตัวที่ต้องการ


2
+1 สำหรับความพยายาม ฉันกลัวว่าภาษาอังกฤษของ OP จะไม่สามารถอ่านคำตอบของคุณได้
mechanical_meat

ฉันเขียนสิ่งนั้นก่อนที่ฉันจะอ่านโปรไฟล์ OPs ตอนนี้ฉันได้อ่านโปรไฟล์ดังกล่าวแล้วและเห็นคำถาม OPs อื่น ๆ อีกมากมาย ฉันเพิ่งลองอีกครั้งคราวนี้ใช้รหัสเท่านั้น :)
James Polley

7
def func(*args): 
    pass

เมื่อคุณกำหนดฟังก์ชันด้วยวิธีนี้*argsอาร์เรย์ของอาร์กิวเมนต์จะถูกส่งไปยังฟังก์ชัน สิ่งนี้ช่วยให้ฟังก์ชันของคุณทำงานโดยไม่ทราบล่วงหน้าว่าจะส่งอาร์กิวเมนต์ไปให้กี่ข้อ

คุณทำสิ่งนี้กับอาร์กิวเมนต์คำหลักด้วยโดยใช้**kwargs:

def func2(**kwargs): 
    pass

ดู: รายการอาร์กิวเมนต์โดยพลการ


ในกรณีของคุณคุณได้กำหนดคลาสที่ทำหน้าที่เหมือนพจนานุกรม วิธีถูกกำหนดให้เป็นdict.poppop(key[, default])

วิธีการของคุณไม่ใช้defaultพารามิเตอร์ แต่โดยการกำหนดวิธีการของคุณด้วย*argsและส่งผ่าน*argsไปยังdict.pop()คุณอนุญาตให้ผู้เรียกใช้defaultพารามิเตอร์

กล่าวอีกนัยหนึ่งคุณควรใช้popวิธีการของชั้นเรียนเช่น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

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')
>>> 

1
ฉันอ่านคำถามหลายข้อตามรายละเอียดในคำตอบอื่น ๆ ของฉัน ฉันยังอ่านโปรไฟล์ OPs และตระหนักว่าคำตอบอื่นของฉันไม่มีประโยชน์ คำตอบนี้ควรแสดงให้เห็นอย่างน้อยก็ส่วนหนึ่งของสิ่งที่ * args ทำซึ่งเป็นสิ่งที่ฉันคาดเดาความสับสนที่แท้จริงของ OPs คือแม้จะมีเรื่องก็ตาม
James Polley

@ เจมส์ +1 สำหรับความพยายามพิเศษ ฉันได้ข้อสรุปเดียวกันเกี่ยวกับคำถามจริง
Peter Hansen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.