ลำดับของคีย์ในพจนานุกรม


110

รหัส:

d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()

print l

['a', 'c', 'b']พิมพ์นี้ ฉันไม่แน่ใจว่าวิธีนี้keys()กำหนดลำดับของคำหลักภายในlได้อย่างไร อย่างไรก็ตามฉันต้องการเรียกคืนคำหลักตามลำดับที่ "ถูกต้อง" ['a', 'b', 'c']การสั่งซื้อที่เหมาะสมของหลักสูตรจะสร้างรายการ


4
ถ้าพจนานุกรม Python เหมือนมากที่สุดจริงๆแล้วมันเป็นตารางแฮช เหนือสิ่งอื่นใดนั่นหมายความว่าไม่รับประกันลำดับของคีย์หรือแม้แต่ระบุ โดยเฉพาะอย่างยิ่งมันจะไม่จำลำดับการเพิ่มคีย์
cHao

4
@cHao: โดยนัยนี้หมายความว่าโปรแกรมของคุณจะไม่แน่นอนหากคุณวนซ้ำองค์ประกอบในพจนานุกรม?
HelloGoodbye

5
@HelloGoodbye: ฉันจะไม่ไปไกลขนาดนั้น ยังมีพฤติกรรมที่คาดเดาได้อยู่ที่นั่น การวนซ้ำแบบเต็มแต่ละครั้งจะเห็นคู่คีย์ / ค่าแต่ละคู่ และในภาษาส่วนใหญ่คุณจะเห็นในลำดับเดียวกันทุกครั้ง แม้ว่าเอกสารจะรับประกันเฉพาะคำสั่งซื้อคุณไม่ควรนับว่าเป็นคำสั่งซื้อที่คุณต้องการ (บางภาษา (เช่น Perl) จะสุ่มลำดับเล็กน้อย - ถูกกล่าวหาว่าเป็นเพราะเหตุผลด้านความปลอดภัย แต่ฉันคิดว่ามันเป็นเพียงการทำให้คุณหลุดจากนิสัยที่ต้องพึ่งพาพฤติกรรมที่ไม่ระบุรายละเอียด :) ฉันไม่คิดว่า Python ค่อนข้าง ที่ชั่วร้าย แต่เอ๊ะ ... )
cHao

1
คำสั่งจะเหมือนเดิมโดยไม่มีการแก้ไขคำสั่ง จากคู่มือ: "ถ้า items (), keys (), values ​​(), iteritems (), iterkeys () และ itervalues ​​() ถูกเรียกโดยไม่มีการแทรกแซงการแก้ไขพจนานุกรมรายการต่างๆจะสอดคล้องกันโดยตรงซึ่งทำให้สามารถสร้าง ของคู่ (value, key) โดยใช้ zip (): pair = zip (d.values ​​(), d.keys ()) "
steveayre

2
@sfranky ฉันคิดว่าสิ่งที่ steveayre หมายถึงคือคำสั่งนั้นเหมือนกันระหว่างสิ่งที่คุณได้รับโดยใช้วิธีการต่างๆที่กล่าวถึงไม่เหมือนกับออร์เดอร์ที่เขียนองค์ประกอบ
bli

คำตอบ:


81

คุณสามารถใช้OrderDict (ต้องใช้ Python 2.7) หรือสูงกว่า

นอกจากนี้โปรดทราบว่าOrderedDict({'a': 1, 'b':2, 'c':3})จะใช้ไม่ได้เนื่องจากdictคุณสร้างด้วย{...}ลืมลำดับขององค์ประกอบไปแล้ว OrderedDict([('a', 1), ('b', 2), ('c', 3)])แต่คุณต้องการที่จะใช้

ตามที่ระบุไว้ในเอกสารสำหรับเวอร์ชันที่ต่ำกว่า Python 2.7 คุณสามารถใช้สูตรนี้ได้


19
โปรดทราบว่าลำดับของ OrderDict คือลำดับการแทรก ปุ่มจะออกมาตามลำดับตัวอักษรก็ต่อเมื่อคุณใส่เข้าไปในลักษณะนั้น
Hugh Bothwell

เป็นสิ่งที่เขาแสดงให้เห็นเป็นตัวอย่างที่เรียบง่าย อาจมีหรือไม่มีความสัมพันธ์กับวิธีที่เขาวางแผนจะใช้งานจริง ก่อนหน้านี้ฉันเคยพบผู้ที่คาดหวังว่า OrderDict จะส่งคืนการแทรกโดยพลการตามลำดับที่เรียงลำดับดังนั้นฉันจึงรู้สึกว่าควรชี้ให้เห็นสิ่งนี้
Hugh Bothwell

141

Python 3.7+

ใน Python 3.7.0ธรรมชาติการเก็บรักษาลำดับการแทรกของdictอ็อบเจ็กต์ได้รับการประกาศให้เป็นส่วนหนึ่งอย่างเป็นทางการของข้อกำหนดภาษา Python ดังนั้นคุณสามารถขึ้นอยู่กับมัน

Python 3.6 (CPython)

ใน Python 3.6 สำหรับการใช้งาน CPython ของ Python พจนานุกรมจะรักษาลำดับการแทรกตามค่าเริ่มต้น นี่ถือเป็นรายละเอียดการใช้งานแม้ว่า; คุณยังควรใช้collections.OrderedDictหากคุณต้องการลำดับการแทรกที่รับประกันในการใช้งาน Python อื่น ๆ

Python> = 2.7 และ <3.6

ใช้collections.OrderedDictชั้นเรียนเมื่อคุณต้องการคลาสdictที่จำลำดับของรายการที่แทรก


เพื่อให้แน่ใจว่าคำสั่งเป็นสิ่งเดียวกับที่สร้างขึ้นเมื่อเราพูดว่า a = {} ใช่ไหม หรือฉันต้องพูดว่า a = dict ()?
shahensha

51
>>> print sorted(d.keys())
['a', 'b', 'c']

ใช้ฟังก์ชันเรียงลำดับซึ่งจะเรียงลำดับการส่งผ่านเข้ามา

.keys()วิธีการส่งกลับกุญแจในการสั่งซื้อโดยพลการ


13
วิธีนี้ใช้ไม่ได้หากคุณต้องการคำสั่งซื้อเดิมและไม่ได้เรียงลำดับ
Simon

13

จากhttp://docs.python.org/tutorial/datastructures.html :

"วิธีการ keys () ของออบเจ็กต์พจนานุกรมจะแสดงรายการของคีย์ทั้งหมดที่ใช้ในพจนานุกรมตามลำดับโดยพลการ (หากคุณต้องการให้จัดเรียงเพียงแค่ใช้ฟังก์ชัน sorted () กับมัน)"


12

เพียงแค่จัดเรียงรายการเมื่อคุณต้องการใช้

l = sorted(d.keys())

1

แม้ว่าคำสั่งจะไม่สำคัญเนื่องจากพจนานุกรมเป็นแฮชแมป ขึ้นอยู่กับลำดับการผลักเข้า:

s = 'abbc'
a = 'cbab'

def load_dict(s):
    dict_tmp = {}
    for ch in s:
        if ch in dict_tmp.keys():
            dict_tmp[ch]+=1
        else:
            dict_tmp[ch] = 1
    return dict_tmp

dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))

เอาท์พุท:
สำหรับสตริง abbc คีย์คือ dict_keys (['a', 'b', 'c'])
สำหรับสตริง cbab คีย์คือ dict_keys (['c', 'b', 'a'])


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