เข้าถึงองค์ประกอบโดยพลการในพจนานุกรมใน Python


507

หาก a mydictไม่ว่างเปล่าฉันจะเข้าถึงองค์ประกอบตามอำเภอใจดังนี้:

mydict[mydict.keys()[0]]

มีวิธีที่ดีกว่าในการทำเช่นนี้?


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

5
ใช่ฉันแค่ต้องเข้าถึงองค์ประกอบใด ๆ ใน dict ดังนั้นนั่นเป็นเหตุผลที่ฉันต้องการเข้าถึงองค์ประกอบแรก
Stan

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

10
ฉันคิดว่ามันเป็นคำถามที่ถูกต้อง หากคุณจำเป็นต้องเข้าถึงองค์ประกอบโดยพลการและคุณแน่ใจว่า dict นั้นไม่ว่างเปล่ามันอาจเป็นความคิดที่ดีที่จะขอ "first" เพราะจำนวนของไอเท็มอาจไม่เป็นที่รู้จัก
kap

7
@MichaelScheper list(mydict.keys())[0]คุณต้องโยนไปที่รายการ:
Daniel Moskovich

คำตอบ:


600

บน Python 3 แบบไม่ทำลายและวนซ้ำ:

next(iter(mydict.values()))

บน Python 2 แบบไม่ทำลายและวนซ้ำ:

mydict.itervalues().next()

ถ้าคุณต้องการให้มันทำงานได้ทั้ง Python 2 และ 3 คุณสามารถใช้sixแพ็คเกจได้:

six.next(six.itervalues(mydict))

แม้ว่า ณ จุดนี้มันค่อนข้างคลุมเครือและฉันต้องการรหัสของคุณมากกว่า

หากคุณต้องการลบรายการใด ๆ ให้ทำ:

key, value = mydict.popitem()

โปรดทราบว่า "ครั้งแรก" อาจไม่ใช่คำที่เหมาะสมที่นี่เพราะdictไม่ใช่ประเภทที่สั่งซื้อใน Python <3.6 dictsสั่งPython 3.6+


35
คุณไม่หมายถึงdict.iterkeys().next()เหรอ
John Machin

12
@ John Machin: คำถามดูเหมือนว่าจะเข้าถึงค่าที่เกี่ยวข้องกับคีย์แรกดังนั้นนั่นคือสิ่งที่ฉันทำในคำตอบเช่นกัน
doublep

5
สิ่งนี้ดูดีกว่า: dict.values().__iter__().__next__():)
Vitaly Zdanevich

17
มันน่ารำคาญที่ dict.keys () ไม่สามารถทำซ้ำได้โดยตรง
รอบ

3
สำหรับ popitem ไม่ทำลายคุณสามารถทำ (ตื้น) คัดลอก:key, value = dict(d).popitem()
Pelle

140

หากคุณต้องการเข้าถึงองค์ประกอบเดียว (เป็นคนแรกโดยบังเอิญเนื่องจาก dicts ไม่รับประกันการสั่งซื้อ) คุณสามารถทำได้ในPython 2 :

my_dict.keys()[0]     -> key of "first" element
my_dict.values()[0]   -> value of "first" element
my_dict.items()[0]    -> (key, value) tuple of "first" element

โปรดทราบว่า (อย่างดีที่สุดจากความรู้ของฉัน) Python ไม่รับประกันว่าการโทรติดต่อ 2 ครั้งต่อเนื่องไปยังวิธีการใด ๆ เหล่านี้จะส่งคืนรายการที่มีลำดับเดียวกัน สิ่งนี้ไม่รองรับกับ Python3

ในPython 3 :

list(my_dict.keys())[0]     -> key of "first" element
list(my_dict.values())[0]   -> value of "first" element
list(my_dict.items())[0]    -> (key, value) tuple of "first" element

90
ใช้งานได้ใน Python 2.x เท่านั้นสำหรับ 3.x คุณต้องใช้list(my_dict.keys())[0]
alldayremix

6
คลาสอันซับซ้อนนี้คืออะไร? แน่นอนlist(my_dict.keys())[0]ไม่ขี้เกียจ?
Evgeni Sergeev

1
เพื่อชี้แจงว่า @alldayremix หมายถึงอะไรกับความคิดเห็นนั้นใน python 3.x my_dict.function () ผลลัพธ์ไม่รองรับการทำดัชนีนี่คือสาเหตุแรกที่เราต้องแปลงมันเป็นรายการจากนั้นเราสามารถใช้ดัชนี [0]
Noki

57

ใน python3 วิธี:

dict.keys() 

คืนค่าในรูปแบบ: dict_keys () เราจะพบข้อผิดพลาดเมื่อมีสมาชิกคนที่ 1 ของคีย์ dict ด้วยวิธีนี้:

dict.keys()[0]
TypeError: 'dict_keys' object does not support indexing

สุดท้ายฉันแปลง dict.keys () เป็น list @ 1st และได้สมาชิกที่ 1 โดยวิธีการต่อรายการ:

list(dict.keys())[0]

นี่เป็นทางออกที่ง่ายที่สุดและทำงานได้ทั้ง python2 และ python3
mattmilten

สำหรับเงินของฉัน ฉันพูดคำตอบนี้ง่ายที่สุด
Thomas Valadez

ใช่ แต่นี่ไม่ได้ตอบคำถาม OP ซึ่งเป็นวิธีที่จะได้รับค่าไม่ใช่กุญแจ
Mike Williamson

1
@ MikeWilliamson หวังว่าผู้อ่านส่วนใหญ่จะรู้วิธีรับค่าที่สอดคล้องกันโดยรับคีย์จาก pict dython
eric

5
ในการรับรายการโดยพลการไม่ใช่คีย์โดยพลการคุณสามารถทำแบบอะนาล็อกlist(dict.values())[0]ได้
jhin

24

เพื่อรับรหัส

next(iter(mydict))

เพื่อรับค่า

next(iter(mydict.values()))

เพื่อรับทั้ง

next(iter(mydict.items())) # or next(iter(mydict.viewitems())) in python 2

สองคนแรกคือ Python 2 และ 3 สองคนสุดท้ายเป็นคนขี้เกียจใน Python 3 แต่ไม่ใช่ใน Python 2


16

ดังที่คนอื่น ๆ กล่าวถึงไม่มี "รายการแรก" เนื่องจากพจนานุกรมไม่มีคำสั่งซื้อที่รับประกัน (มีการใช้งานเป็นตารางแฮช) ตัวอย่างเช่นหากคุณต้องการค่าที่สอดคล้องกับคีย์ที่เล็กที่สุดthedict[min(thedict)]จะทำเช่นนั้น หากคุณสนใจลำดับที่ใส่กุญแจนั่นคือ "แรก" คุณหมายถึง "แทรกเร็ว" จากนั้นใน Python 3.1 คุณสามารถใช้คอลเลกชัน OrderedDictซึ่งอยู่ใน Python 2.7 ที่กำลังจะมาถึง สำหรับรุ่นเก่าของงูหลามดาวน์โหลดติดตั้งและใช้ย้ายกลับ Dict สั่งซื้อ (2.4 และต่อมา) ซึ่งคุณสามารถหาได้ที่นี่

Python 3.7 ตอนนี้ใส่ dicts แล้ว


11

แล้วเรื่องนี้ล่ะ ยังไม่ได้กล่าวถึงที่นี่

py 2 & 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2

5
dict.values()ส่งคืนมุมมองดังนั้นควรเป็น O (1) list(a)ส่งคืนรายการใหม่ดังนั้นจะเป็น O (n)
boycy

ดูเหมือนว่าจะไม่ทำงานใน python2 ถ้า a = {"a": {"1"}}
qasimzee

11

การเพิกเฉยปัญหาที่เกิดขึ้นโดยรอบการสั่งซื้อแบบคิดเลขอาจจะดีกว่า:

next(dict.itervalues())

วิธีนี้เราหลีกเลี่ยงการค้นหารายการและสร้างรายการของคีย์ที่เราไม่ได้ใช้

Python3

next(iter(dict.values()))

2
ค่า () จะทำสำเนาของค่าทั้งหมด (เช่นเดียวกับคีย์ () สำหรับคีย์) ดังนั้นสิ่งนี้จะทำให้การดำเนินการหลายอย่าง O (n ^ 2)
Glenn Maynard

เวอร์ชั่น OPs จะเป็นเช่นไร? ฉันจะเปลี่ยนสิ่งนี้เพื่อใช้ตัววนซ้ำแล้ว
Matt Joiner

4
นี่เป็น Python 2 เท่านั้นสำหรับ Python 3 เราต้องnext(iter(dict.values()))ได้ผลลัพธ์เดียวกันโดยไม่ต้องสร้างรายการ
kap


2

คุณสามารถทำได้:

for k in sorted(d.keys()):
    print d[k]

สิ่งนี้จะทำให้คุณได้รับการเรียงลำดับอย่างต่อเนื่อง (เทียบกับbuiltin .hash () ฉันเดา) ชุดของคีย์ที่คุณสามารถดำเนินการได้หากการเรียงลำดับมีความหมายใด ๆ กับคุณ นั่นหมายความว่าตัวอย่างประเภทตัวเลขจะถูกจัดเรียงอย่างสม่ำเสมอแม้ว่าคุณจะขยายพจนานุกรม

ตัวอย่าง

# lets create a simple dictionary
d = {1:1, 2:2, 3:3, 4:4, 10:10, 100:100}
print d.keys()
print sorted(d.keys())

# add some other stuff
d['peter'] = 'peter'
d['parker'] = 'parker'
print d.keys()
print sorted(d.keys())

# some more stuff, numeric of different type, this will "mess up" the keys set order
d[0.001] = 0.001
d[3.14] = 'pie'
d[2.71] = 'apple pie'
print d.keys()
print sorted(d.keys())

โปรดทราบว่าพจนานุกรมจะถูกจัดเรียงเมื่อพิมพ์ แต่ชุดคีย์คือ hashmap เป็นหลัก!


2

สำหรับ Python 2 และ 3:

import six

six.next(six.itervalues(d))

สิ่งนี้ไม่ได้ให้คำตอบสำหรับคำถาม หากต้องการวิจารณ์หรือขอคำชี้แจงจากผู้แต่งโปรดแสดงความคิดเห็นใต้โพสต์ของพวกเขา
Martin Tournoij

ตรงนี้ตอบคำถามIs there any better way to do this?ในลักษณะสั้น ๆ
oblalex

คำตอบนี้ได้รับสองครั้งแล้วหนึ่งในนั้นได้รับในเว็บไซต์นี้เกือบ 5 ปี นี่คือความคิดเห็นเกี่ยวกับคำตอบอื่น (ตาม: นี่คือวิธีการปรับปรุงคำตอบเพื่อให้ทำงานได้กับทั้ง Python 2 และ 3 ) ไม่ใช่คำตอบ "ใหม่" เช่นนี้ ระบบตรวจสอบของ SO วางไว้โดยอัตโนมัติบันทึกค่อนข้างช่วยเหลือในกรณีนี้ ...
มาร์ติน Tournoij

ไม่ครับท่าน. คุณเพิ่มตัวแปรนี้ใน 5 คำตอบของคุณเมื่อ 17 ชั่วโมงที่แล้ว 1 ชั่วโมงหลังจากที่ฉันเขียนคำตอบนี้ ลองใช้ 'ค้นหา' บนหน้านี้สำหรับคำว่า 'หก' และคุณจะพบเพียง 6 คู่เท่านั้นในคำตอบ 2 ข้อนี้ อย่างไรก็ตามคำตอบนี้รบกวนคุณจริงๆหรือ? ฉันคิดว่านี่อาจช่วยคนอื่นในอนาคตและนี่ก็โอเค ดังนั้นการจัดการคืออะไร?
oblalex

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

0
first_key, *rest_keys = mydict

11
ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติฐานที่คุณทำ
Suraj Rao

-1

ไม่มีไลบรารีภายนอกทำงานได้ทั้ง Python 2.7 และ 3.x:

>>> list(set({"a":1, "b": 2}.values()))[0]
1

สำหรับคีย์ Aribtrary เพียงแค่ปล่อย. value ()

>>> list(set({"a":1, "b": 2}))[0]
'a'

-2

การจัดคลาสย่อยdictเป็นวิธีหนึ่ง แต่ไม่มีประสิทธิภาพ ที่นี่หากคุณระบุจำนวนเต็มมันจะกลับมาd[list(d)[n]]มิฉะนั้นเข้าถึงพจนานุกรมตามที่คาดไว้:

class mydict(dict):
    def __getitem__(self, value):
        if isinstance(value, int):
            return self.get(list(self)[value])
        else:
            return self.get(value)

d = mydict({'a': 'hello', 'b': 'this', 'c': 'is', 'd': 'a',
            'e': 'test', 'f': 'dictionary', 'g': 'testing'})

d[0]    # 'hello'
d[1]    # 'this'
d['c']  # 'is'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.