การเข้าถึงองค์ประกอบของพจนานุกรม Python ด้วยดัชนี


118

พิจารณาคำสั่งเช่น

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

ฉันจะเข้าถึงเช่นองค์ประกอบเฉพาะของพจนานุกรมนี้ได้อย่างไร ตัวอย่างเช่นฉันต้องการพิมพ์องค์ประกอบแรกหลังจากจัดรูปแบบองค์ประกอบแรกของ Apple ซึ่งในกรณีของเราคือ 'อเมริกัน' เท่านั้น?

ข้อมูลเพิ่มเติมโครงสร้างข้อมูลข้างต้นสร้างขึ้นโดยการแยกวิเคราะห์ไฟล์อินพุตในฟังก์ชัน python เมื่อสร้างขึ้นแล้วอย่างไรก็ตามจะยังคงเหมือนเดิมสำหรับการรันนั้น

ฉันใช้โครงสร้างข้อมูลนี้ในฟังก์ชันของฉัน

ดังนั้นหากไฟล์มีการเปลี่ยนแปลงในครั้งต่อไปที่เรียกใช้แอปพลิเคชันนี้เนื้อหาของไฟล์จะแตกต่างกันดังนั้นเนื้อหาของโครงสร้างข้อมูลนี้จะแตกต่างกัน แต่รูปแบบจะเหมือนกัน คุณจะเห็นว่าฉันอยู่ในฟังก์ชันของฉันฉันไม่รู้ว่าองค์ประกอบแรกใน Apple คือ 'อเมริกัน' หรืออย่างอื่นดังนั้นฉันจึงไม่สามารถใช้ 'อเมริกัน' เป็นกุญแจได้โดยตรง


2
คุณช่วยยกตัวอย่างผลลัพธ์ที่คุณคาดหวังได้ไหม
Björn Pollex

3
คุณต้องการทำอะไรกับโครงสร้างนี้? และคุณรู้จักคีย์ของคำสั่ง ('Apple' และ 'Grapes' ในตัวอย่างของคุณ) หรือไม่? หรือคุณรู้แค่ว่าคุณจะได้รับคำสั่งจากบงการ?
juanchopanza

6
dictอย่าเรียกพจนานุกรมของคุณ คำว่า 'dict' เป็นคีย์เวิร์ดใน Python อยู่แล้ว ใช้อย่างอื่นเช่นmydict.
Rick สนับสนุน Monica

หมายเหตุ: คำถามนี้เกี่ยวกับการเข้าถึงองค์ประกอบ dict โดยดัชนีซึ่งไม่สมเหตุสมผลเพราะไม่เรียงลำดับตามลำดับ สำหรับคำถามเกี่ยวกับการเข้าถึงองค์ประกอบใน Dict ซ้อนกันให้ดูงูหลาม - ค่าการเข้าถึงซ้อนอยู่ในพจนานุกรม
Aran-Fey

@ Aran-Fey: สิ่งที่ไม่เรียงลำดับมีลำดับที่แท้จริง Unordered! = no order.
Jamie Marshall

คำตอบ:


124

ระบุว่าเป็นพจนานุกรมที่คุณเข้าถึงได้โดยใช้ปุ่ม การจัดเก็บพจนานุกรมใน "Apple" ให้ทำดังต่อไปนี้:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

และรับจำนวนคนอเมริกัน (16) ให้ทำดังนี้:

>>> mydict["Apple"]["American"]
'16'

9
เราจะทำแบบไดนามิกโดยไม่รู้ความลึกขององค์ประกอบได้อย่างไร?
Ethan Bierlein

3
คุณต้องการทราบอะไรกันแน่? คุณสามารถรับคีย์ของพจนานุกรม.keys()เพื่อให้คุณสามารถเข้าถึงได้แบบไดนามิก
Morten Kristensen

3
เช่นหากคุณมีพจนานุกรมที่ไม่ทราบความลึกเช่นพจนานุกรมซ้อนและคุณมีองค์ประกอบ"n"ที่ระดับความลึกที่ไม่รู้จักเก็บไว้ในองค์ประกอบที่ไม่รู้จัก
Ethan Bierlein

1
นั่นเป็นคำถามที่กว้างมาก เมื่อพิจารณาโครงสร้างข้อมูลของคุณแล้วคุณจะต้องเขียนฟังก์ชันหรือคลาสเพื่อจัดการกับมันอย่างเหมาะสม บางทีคุณอาจจัดหากุญแจและกลยุทธ์ในการพยายามค้นหากุญแจ
Morten Kristensen

1
@EthanBierlein ใช้: 'สำหรับคีย์ค่าใน dictionary.iteritems ()' เพื่อเข้าถึงทั้งคีย์และค่า
danius

25

ถ้าคำถามคือถ้าฉันรู้ว่าฉันมีคำสั่งที่มีคำว่า 'Apple' เป็นผลไม้และ 'อเมริกัน' เป็นแอปเปิ้ลประเภทหนึ่งฉันจะใช้:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

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

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

หรือดีกว่าดังนั้นคุณไม่จำเป็นต้องทำซ้ำตามคำสั่งทั้งหมดโดยไม่จำเป็นหากคุณรู้ว่ามีเพียง Apple เท่านั้นที่มีประเภท American:

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

ในกรณีเหล่านี้ทั้งหมดไม่สำคัญว่าพจนานุกรมจะจัดเก็บรายการใดไว้ หากคุณกังวลเกี่ยวกับคำสั่งซื้อจริงๆคุณอาจพิจารณาใช้OrderedDict:

http://docs.python.org/dev/library/collections.html#collections.OrderedDict


20

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

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

ดังนั้นคุณต้องทำซ้ำในพจนานุกรมหลักของคุณ หากคุณต้องการพิมพ์หรือเข้าถึงคีย์พจนานุกรมแรกทั้งหมดในsampleDict.values()รายการคุณอาจใช้สิ่งนี้:

for key, value in sampleDict.items():
    print value.keys()[0]

หากคุณต้องการเข้าถึงคีย์แรกของรายการแรกsampleDict.values()อาจเป็นประโยชน์:

print sampleDict.values()[0].keys()[0]

หากคุณใช้ตัวอย่างที่คุณให้ไว้ในคำถามฉันหมายถึง:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

ผลลัพธ์ของรหัสแรกคือ:

American
Indian

และผลลัพธ์ของรหัสที่สองคือ:

American

10

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

มีห้องสมุดที่น่าสนใจเกี่ยวกับเรื่องนี้ใน pypi นี่คือการค้นหาอย่างรวดเร็วสำหรับคุณ

ในกรณีเฉพาะของคุณdict_diggerดูเหมือนจะเหมาะสม

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None

8

คุณสามารถใช้dict['Apple'].keys()[0]เพื่อให้ได้ที่สำคัญเป็นครั้งแรกในAppleพจนานุกรม Americanแต่ไม่มีการรับประกันว่ามันจะไม่มี ลำดับของคีย์ในพจนานุกรมอาจเปลี่ยนแปลงได้ขึ้นอยู่กับเนื้อหาของพจนานุกรมและลำดับที่เพิ่มคีย์


เว้นแต่คุณจะใช้OrderedDictในcollectionsห้องสมุด
Escachator

7

ฉันรู้ว่านี่อายุ 8 ขวบ แต่ดูเหมือนจะไม่มีใครอ่านและตอบคำถามจริงๆ

คุณสามารถเรียก. value () ในคำสั่งเพื่อรับรายการของคำสั่งภายในและเข้าถึงได้โดยดัชนี

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']

2
'dict_values' object does not support indexing ที่น่าสนใจฉันพยายามนี้และได้ เดาว่าคำตอบนี้ต้องการการอัปเดตเนื่องจากคุณต้องตัดค่า dict_values ​​เพื่อกู้คืนรายการ
Yuca

1
@Yucca - คุณถูกต้องฉันไม่ได้ทดสอบรหัสของฉัน คำตอบได้รับการอัปเดตแล้ว
Jamie Marshall

4

คุณไม่สามารถพึ่งพาคำสั่งของพจนานุกรมได้ แต่คุณสามารถลองสิ่งนี้:

dict['Apple'].items()[0][0]

หากคุณต้องการรักษาคำสั่งซื้อไว้คุณอาจต้องใช้สิ่งนี้: http://www.python.org/dev/peps/pep-0372/#ordered-dict-api


3

ตัวอย่างง่ายๆเพื่อทำความเข้าใจวิธีการเข้าถึงองค์ประกอบในพจนานุกรม: -

สร้างพจนานุกรม

d = {'dog' : 'bark', 'cat' : 'meow' } 
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))

สำรวจเพิ่มเติมเกี่ยวกับพจนานุกรม Python และเรียนรู้แบบโต้ตอบที่นี่ ...


1

มีเพียงไม่กี่คนที่ปรากฏตัวขึ้นแม้จะมีคำตอบมากมายสำหรับคำถามนี้เพื่อชี้ให้เห็นว่าพจนานุกรมเป็นการแมปที่ไม่ได้เรียงลำดับและอื่น ๆ (จนถึงคำสั่งการแทรกด้วย Python 3.7) ความคิดของรายการ "แรก" ในพจนานุกรมที่สร้างขึ้นตามตัวอักษร ไม่มีความรู้สึก และแม้กระทั่งOrderedDictสามารถเข้าถึงได้โดยดัชนีตัวเลขโดยใช้ความอัปลักษณ์เช่นmydict[mydict.keys()[0]](Python 2 เท่านั้นเนื่องจากใน Python 3 keys()เป็นตัววนซ้ำที่ไม่สามารถห้อยลงได้)

ตั้งแต่ 3.7 เป็นต้นไปและในทางปฏิบัติใน 3,6 เช่นกัน - พฤติกรรมใหม่ได้รับการแนะนำแล้ว แต่ไม่รวมเป็นส่วนหนึ่งของข้อกำหนดภาษาจนถึง 3.7 - การวนซ้ำคีย์ค่าหรือรายการของคำสั่ง (และฉันเชื่อว่า a ตั้งค่าด้วย) จะให้วัตถุที่แทรกน้อยที่สุดก่อน ยังไม่มีวิธีง่ายๆในการเข้าถึงด้วยดัชนีตัวเลขของการแทรก

สำหรับคำถามเกี่ยวกับการเลือกและ "การจัดรูปแบบ" รายการหากคุณทราบคีย์ที่ต้องการดึงข้อมูลในพจนานุกรมโดยปกติคุณจะใช้คีย์ดังกล่าวเป็นตัวห้อยเพื่อดึงข้อมูล ( my_var = mydict['Apple'])

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

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

คุณอาจใช้:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

ภายใต้ระบอบการปกครองนี้รายการแรกmylist[0]ในรูปแบบรายการ endexed ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5})คลาสสิกและความคุ้มค่าของมันคือ คุณสามารถทำซ้ำรายการทั้งหมดได้ดังนี้:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

แต่ถ้าคุณรู้ว่าคุณกำลังมองหาคีย์ "Apple" ทำไมคุณไม่ใช้ dict แทนล่ะ?

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


0

ด้วยฟังก์ชั่นเล็ก ๆ ต่อไปนี้การขุดลงในพจนานุกรมรูปต้นไม้กลายเป็นเรื่องง่าย:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

ตอนนี้dig(mydict, "Apple.Mexican")ผลตอบแทน10ในขณะที่อัตราผลตอบแทนทรีย่อยdig(mydict, "Grape") {'Arabian':'25','Indian':'20'}ถ้าคีย์ไม่ได้มีอยู่ในพจนานุกรมให้ผลตอบแทนdigNone

โปรดทราบว่าคุณสามารถเปลี่ยน (หรือกำหนดพารามิเตอร์) ตัวคั่นถ่านจาก "." ได้อย่างง่ายดาย ถึง '/', '|' เป็นต้น

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