พจนานุกรม Python: คีย์ () และค่า () เรียงตามลำดับเสมอกันหรือไม่


312

ดูเหมือนว่ารายการที่ส่งคืนโดยkeys()และvalues()เมธอดของพจนานุกรมมักจะมีการแมปแบบ 1 ต่อ 1 เสมอ (สมมติว่าพจนานุกรมไม่มีการเปลี่ยนแปลงระหว่างการเรียกใช้ 2 เมธอด)

ตัวอย่างเช่น:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

หากคุณไม่เปลี่ยนพจนานุกรมระหว่างการโทรkeys()และการโทรvalues()เป็นความผิดหรือไม่ที่จะถือว่าการ for-loop ข้างต้นจะพิมพ์ True เสมอ? ฉันไม่พบเอกสารที่ยืนยันสิ่งนี้


1
ใน CPython 3.7 (ขึ้นไปอย่างน่าจะเป็น) คุณอาจเชื่อถือได้ตามลำดับการวนซ้ำของคำสั่งการจับคู่พจนานุกรม mail.python.org/pipermail/python-dev/2017-December/151283.html
BallpointBen

@BallpointBen อยู่ใน CPython 3.6 ขึ้นไปและการใช้งาน Python อื่น ๆ ทั้งหมดเริ่มต้นด้วย Python 3.7
Boris

คำตอบ:


353

พบสิ่งนี้:

ถ้าitems(), keys(), values(), iteritems(), iterkeys()และ itervalues()จะเรียกว่ามีการปรับเปลี่ยนไม่แทรกแซงในพจนานุกรมรายการจะสอดคล้องโดยตรง

เกี่ยวกับเอกสาร 2.xและเอกสาร 3.x


5
เห็นได้ชัดว่าคำสั่งในเอกสาร 3.x มีความชัดเจน: "คำสั่งของรายการจะตรง"
Shaohua Li

4
ข้อความนี้หายไปในเอกสารประกอบ 3.7 ฉันสามารถสันนิษฐานได้ว่าเป็นเพราะ "Dict เก็บคำสั่งแทรก" ใน 3.7: mail.python.org/pipermail/python-dev/2017-December/151283.html
EliadL

80

ใช่สิ่งที่คุณสังเกตเห็นนั้นเป็นคุณสมบัติที่รับประกันแน่นอน - keys (), values ​​() และ items () รายการส่งคืนตามลำดับหากไม่ได้เปลี่ยน dict iterkeys () & c ยังวนซ้ำในลำดับเดียวกันกับรายการที่เกี่ยวข้อง


1
อย่างไรก็ตามในกรณีที่มีการเปลี่ยนแปลงรายการPandas dataframeเสนอทางเลือกที่สามารถอัปเดตหรือลบรายการและลำดับและตำแหน่งดัชนีของรายการในโครงสร้างคล้าย dict ยังคงได้รับการแก้ไข
วิลล์

48

ใช่รับประกันใน python 2.x :

หากคีย์ค่าและมุมมองรายการถูกวนซ้ำโดยไม่มีการแก้ไขการแทรกแซงพจนานุกรมลำดับของรายการจะสอดคล้องกันโดยตรง


7

ใช่. เริ่มต้นด้วย CPython 3.6 พจนานุกรมกลับรายการในการสั่งซื้อที่คุณแทรกพวกเขา

ดูรายละเอียดส่วนที่ระบุว่านี่เป็นรายละเอียดการใช้งาน ลักษณะการทำงานนี้มีการรับประกันใน CPython 3.6 และจำเป็นสำหรับการใช้หลามอื่น ๆ ทั้งหมดที่เริ่มต้นด้วยงูหลาม 3.7


6

อ้างอิงที่ดีถึงเอกสาร นี่คือวิธีที่คุณสามารถรับประกันการสั่งซื้อโดยไม่คำนึงถึงเอกสาร / การใช้งาน:

k, v = zip(*d.iteritems())

1
ใน python3.x ใช้ dict.items ()
Good Will

4

ตามที่http://docs.python.org/dev/py3k/library/stdtypes.html#dictionary-view-objectsวิธีการคีย์ () ค่า () และรายการ () ของ dict จะส่งคืนตัววนซ้ำที่สอดคล้องกันซึ่งคำสั่ง สอดคล้อง อย่างไรก็ตามฉันไม่สามารถค้นหาการอ้างอิงถึงเอกสารอย่างเป็นทางการสำหรับ python 2.x สำหรับสิ่งเดียวกัน

ดังนั้นเท่าที่ฉันสามารถบอกได้คำตอบคือใช่ แต่เฉพาะใน python 3.0+ เท่านั้น


4

สำหรับสิ่งที่คุ้มค่ารหัสการผลิตที่ใช้งานหนักบางอย่างที่ฉันเขียนขึ้นอยู่กับสมมติฐานนี้และฉันไม่เคยมีปัญหากับมัน ฉันรู้ว่ามันไม่ได้ทำให้เป็นจริงแม้ว่า :-)

หากคุณไม่ต้องการเสี่ยงฉันจะใช้ iteritems () ถ้าทำได้

for key, value in myDictionary.iteritems():
    print key, value

-2

ฉันไม่พอใจกับคำตอบเหล่านี้เนื่องจากฉันต้องการให้แน่ใจว่าค่าที่ส่งออกมีการเรียงลำดับเดียวกันแม้ว่าจะใช้ dicts ต่างกันก็ตาม

ที่นี่คุณระบุล่วงหน้าของคำสั่งซื้อคีย์ค่าที่ส่งคืนจะมีลำดับเดียวกันเสมอแม้ว่า dict จะเปลี่ยนแปลงหรือคุณใช้ dict อื่น

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.