คุณจะหาคีย์แรกในพจนานุกรมได้อย่างไร


203

ฉันกำลังพยายามให้โปรแกรมของฉันพิมพ์ออกมา"banana"จากพจนานุกรม อะไรจะเป็นวิธีที่ง่ายที่สุดในการทำเช่นนี้?

นี่คือพจนานุกรมของฉัน:

prices = {
    "banana" : 4,
    "apple" : 2,
    "orange" : 1.5,
    "pear" : 3
}

35
พจนานุกรมใน Python ไม่มีการเรียงลำดับจึงไม่มี "คีย์แรก" ดูที่นี่
David Robinson

2
คุณต้องการพิมพ์คำว่า "banana" หรือค่าที่เกี่ยวข้องกับ "Banana" (4 ในกรณีนี้) อย่างแท้จริงหรือไม่?
พอล H

to print out banana with a FOR loop, so when I run it, each key would also be printed outคุณหมายถึงfor k in prices: print kอะไร ที่จะพิมพ์คีย์ทั้งหมดในพจนานุกรม
David Robinson


8
ไปที่ความคิดเห็นแรก: ในพจนานุกรม python 3.6+ ได้รับคำสั่ง (ดูstackoverflow.com/questions/39980323/… )
Egirus Ornila

คำตอบ:


289

ในเวอร์ชัน Python ที่สั่ง dicts จริง ๆ คุณสามารถทำได้

my_dict = {'foo': 'bar', 'spam': 'eggs'}
next(iter(my_dict)) # outputs 'foo'

สำหรับการสั่งซื้อ dicts คุณต้องใช้ Python 3.7+ หรือ 3.6+ ถ้าคุณโอเคกับการพึ่งพารายละเอียดทางเทคนิค

สำหรับ Python เวอร์ชั่นก่อนหน้าไม่มี "ปุ่มแรก"


31
ถ้าคุณต้องการทั้งคีย์และค่าใน Python 3:next(iter( my_dict.items() ))
Jonathan H

@RyanHaining Python dicts ได้รับคำสั่งจากการแทรกเริ่มต้นด้วย CPython 3.6 และการใช้งาน Python อื่น ๆ ที่เริ่มต้นด้วย Python 3.7
Boris

1
คำตอบนี้ทำให้เมาในการดีบั๊กของฉันที่ฉันรอ 6 ชั่วโมงเพื่อไปที่จุดพัก นี่มันน่ารำคาญมาก
Michael

133

พจนานุกรมไม่ได้ถูกจัดทำดัชนี แต่เรียงตามลำดับแล้ว ต่อไปนี้จะให้คีย์แรกที่มีอยู่กับคุณ:

list(my_dict.keys())[0]

26
จะไม่ง่ายกว่าแค่ใส่list(my_dict)[0]เพราะมันจะเรียกคืนรายชื่อของคีย์หรือไม่?
Jean-Francois T.

@ ฌองฟรานโคอิส ใช่
Ryan Haining

พจนานุกรมได้รับการสั่งซื้อใน CPython 3.6 และการใช้งาน Python อื่น ๆ ทั้งหมดที่เริ่มต้นด้วย Python 3.7
Boris

53

อัปเดต:ตั้งแต่ Python 3.7 มีการรักษาลำดับการแทรกดังนั้นคุณไม่จำเป็นต้องใช้OrderedDictที่นี่ คุณสามารถใช้วิธีการด้านล่างด้วยวิธีปกติdict

เปลี่ยนเป็นเวอร์ชั่น 3.7:คำสั่งพจนานุกรมรับประกันว่าจะเป็นคำสั่งแทรก พฤติกรรมนี้เป็นรายละเอียดการใช้งานของ CPython จาก 3.6

แหล่ง


Python 3.6 และก่อนหน้า *

หากคุณกำลังพูดถึงเรื่องปกติdict"ปุ่มแรก" นั้นไม่ได้มีความหมายอะไรเลย ปุ่มไม่ได้เรียงในแบบที่คุณสามารถพึ่งพาได้ หากคุณทำซ้ำมากกว่าdictคุณจะไม่ได้รับ"banana"สิ่งแรกที่คุณเห็น

หากคุณต้องการเก็บสิ่งต่าง ๆ ตามลำดับคุณต้องใช้OrderedDictพจนานุกรมที่ไม่ใช่พจนานุกรมธรรมดา

import collections
prices  = collections.OrderedDict([
        ("banana", 4),
        ("apple", 2),
        ("orange", 1.5),
        ("pear", 3),
])

หากคุณต้องการเห็นกุญแจทั้งหมดตามลำดับคุณสามารถทำได้โดยวนซ้ำ ๆ

for k in prices:
    print(k)

คุณสามารถเลือกใส่คีย์ทั้งหมดลงในรายการแล้วทำงานกับมันได้

ks = list(prices)
print(ks[0]) # will print "banana"

วิธีที่เร็วกว่าในการรับองค์ประกอบแรกโดยไม่สร้างรายการคือการเรียกnextใช้ตัววนซ้ำ สิ่งนี้ไม่ได้พูดคุยเป็นอย่างดีเมื่อพยายามรับnthองค์ประกอบ

>>> next(iter(prices))
'banana'

* CPython รับประกันคำสั่งแทรกเป็นรายละเอียดการใช้งานใน 3.6


ขอบคุณสำหรับคำแนะนำ. ฉันขอโทษที่ไม่ชัดเจนมากขึ้น ฉันแค่พยายามค้นหารหัสที่จะให้ฉันพิมพ์ "Banana" ไม่ใช่ค่าที่เกี่ยวข้อง ขอบคุณสำหรับทุกท่าน!
slagoy

33

สำหรับ Python 3 ด้านล่างกำจัดค่าใช้จ่ายในการแปลงรายการ:

first = next(iter(prices.values()))

10

dictประเภทคือการเรียงลำดับการทำแผนที่ดังนั้นจึงไม่มีสิ่งดังกล่าวเป็น "ครั้งแรก" องค์ประกอบ

collections.OrderedDictสิ่งที่คุณต้องการอาจจะเป็น


หรือบางทีอาจจะเป็นชื่อที่ไม่เปลี่ยนชื่อ
Joran Beasley

สิ่งนี้เปลี่ยนไปจาก Python 3.6 พจนานุกรมได้รับคำสั่งในขณะนี้
misantroop

1
ในทางเทคนิคแล้วคุณต้องการองค์ประกอบแรกของปุ่มพจนานุกรมหากคุณมั่นใจว่ามีเพียงปุ่มเดียวเท่านั้น
DBX12

หนึ่งสามารถพูดรายการแรกในขณะที่ซ้ำกว่า dict ซึ่ง ifs แก้ไข แต่โชคดีที่คิดออกว่า
demongolem

6

ดังนั้นฉันจึงพบหน้านี้ในขณะที่พยายามเพิ่มประสิทธิภาพสิ่งสำหรับการรับกุญแจเท่านั้นในพจนานุกรมของความยาวที่รู้จัก 1 และส่งคืนกุญแจเท่านั้น กระบวนการด้านล่างนี้เป็นวิธีที่เร็วที่สุดสำหรับพจนานุกรมทั้งหมดที่ฉันลองจนถึงขนาด 700

ฉันลอง 7 วิธีที่แตกต่างกันและพบว่าวิธีนี้ดีที่สุดในปี 2014 Macbook กับ Python 3.6:

def first_5():
    for key in biased_dict:
        return key

ผลลัพธ์ของการทำโปรไฟล์คือ:

  2226460 / s with first_1
  1905620 / s with first_2
  1994654 / s with first_3
  1777946 / s with first_4
  3681252 / s with first_5
  2829067 / s with first_6
  2600622 / s with first_7

วิธีการทั้งหมดที่ฉันพยายามอยู่ที่นี่:

def first_1():
    return next(iter(biased_dict))


def first_2():
    return list(biased_dict)[0]


def first_3():
    return next(iter(biased_dict.keys()))


def first_4():
    return list(biased_dict.keys())[0]


def first_5():
    for key in biased_dict:
        return key


def first_6():
    for key in biased_dict.keys():
        return key


def first_7():
    for key, v in biased_dict.items():
        return key

1
ดังนั้นการทำเพื่อลูปและส่งกลับคีย์แรก (first_5) เป็นจริงเร็วที่สุดเท่าที่ฉันเห็น? นอกจากนี้ยังเป็นการเปรียบเทียบที่ดีของวิธีการต่าง ๆ
PiMathCLanguage

1
ใช่และไม่ใช่แค่เร็วที่สุด แต่เร็วที่สุดโดยไมล์ประเทศ นอกจากนี้ยังง่ายที่สุดในการอ่านสะดวก
turiyag

4

อย่างง่ายคำตอบตามฉันจะเป็น

first = list(prices)[0]

การแปลงพจนานุกรมเป็นลิสต์จะเอาท์พุทคีย์และเราจะเลือกคีย์แรกจากรายการ


สำหรับ python3 ไม่จำเป็นต้องสร้างรายการใหม่ทั้งหมดเพื่อดึงองค์ประกอบแรกเท่านั้น ใช้งานได้ดีกว่าnext(iter(prices))ตามคำแนะนำอื่น ๆ
normanius

1

อย่างที่คนอื่นหลายคนชี้ให้เห็นไม่มีค่าแรกในพจนานุกรม การเรียงลำดับเป็นแบบสุ่มและคุณไม่สามารถวางใจได้ว่าการเรียงลำดับจะเหมือนกันทุกครั้งที่คุณเข้าถึงพจนานุกรม อย่างไรก็ตามหากคุณต้องการพิมพ์ปุ่มมีสองสามวิธี:

for key, value in prices.items():
    print(key)

เมธอดนี้ใช้การกำหนดค่า tuple เพื่อเข้าถึงคีย์และค่า มีประโยชน์ถ้าคุณต้องการเข้าถึงทั้งกุญแจและค่าด้วยเหตุผลบางอย่าง

for key in prices.keys():
    print(key)

สิ่งนี้จะช่วยให้เข้าถึงคีย์ได้เฉพาะเมื่อkeys()วิธีการบ่งบอกถึง


1

d.keys () [0] เพื่อรับรหัสบุคคล

Update: - @AlejoBernardin ไม่แน่ใจว่าทำไมคุณถึงบอกว่ามันไม่ทำงาน ที่นี่ฉันตรวจสอบและใช้งานได้ นำเข้าคอลเล็กชัน

prices  = collections.OrderedDict((

    ("banana", 4),
    ("apple", 2),
    ("orange", 1.5),
    ("pear", 3),
))
prices.keys()[0]

'กล้วย'


ไปด้วยจำนวนคะแนนเสียงทำไมนี่ไม่ใช่ทางออกที่ดีที่สุด?
GuSuku

18
สิ่งนี้ใช้ได้ใน python2 แต่ไม่ใช่ python3 ใน python3 dict.keys()ส่งคืน a 'dict_keys' objectแทนlistซึ่งไม่สนับสนุนการทำดัชนี
mavix

TypeError: วัตถุ 'dict_keys' ไม่รองรับการสร้างดัชนี
anilbey

0

ใช้สำหรับห่วงที่ช่วงผ่านคีย์ทั้งหมดในprices:

for key, value in prices.items():
     print key
     print "price: %s" %value

ตรวจสอบให้แน่ใจว่าคุณเปลี่ยนprices.items()เป็นprices.iteritems()ถ้าคุณใช้ Python 2.x


0

หากคุณต้องการคีย์แรกจากพจนานุกรมคุณควรใช้สิ่งที่หลายคนแนะนำมาก่อน

first = next(iter(prices))

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

first, *rest = prices

เช่นเดียวกันกับค่าโดยการแทนที่pricesด้วยprices.values()และสำหรับทั้งคีย์และค่าคุณสามารถใช้การกำหนดการคลายแพ็กเกจได้

>>> (product, price), *rest = prices.items()
>>> product
'banana'
>>> price
4

หมายเหตุ:คุณอาจถูกล่อลวงให้ใช้first, *_ = pricesเพื่อรับคีย์แรกเท่านั้น แต่โดยทั่วไปฉันจะแนะนำการใช้งานนี้ยกเว้นพจนานุกรมสั้นมากเนื่องจากมันวนซ้ำทุกคีย์และการสร้างรายการสำหรับrestโอเวอร์เฮดบางรายการ

หมายเหตุ:ตามที่กล่าวไว้โดยลำดับการแทรกอื่น ๆ จะถูกเก็บรักษาไว้จากpython 3.7 (หรือในทางเทคนิค 3.6) และสูงกว่าในขณะที่การใช้งานก่อนหน้านี้ควรถูกพิจารณาว่าเป็นคำสั่งที่ไม่ได้กำหนด


-3

วิธีที่ง่ายที่สุดคือ:

first_key = my_dict.keys()[0]

แต่บางครั้งคุณควรระวังให้มากขึ้นและรับรองว่าเอนทิตีของคุณเป็นรายการที่มีค่าดังนั้น:

first_key = list(my_dict.keys())[0]

3
มันเพิ่มTypeError: 'dict_keys' object is not subscriptableอย่างน้อยด้วย Python 3.8
Eerik Sven Puudist
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.