Truy cập các phần tử của từ điển Python theo chỉ mục


117

Hãy xem xét một mệnh lệnh như

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

Làm cách nào để truy cập ví dụ như một phần tử cụ thể của từ điển này? ví dụ: tôi muốn in phần tử đầu tiên sau một số định dạng phần tử đầu tiên của Apple mà trong trường hợp của chúng tôi là chỉ 'Mỹ'?

Thông tin bổ sung Cấu trúc dữ liệu trên được tạo bằng cách phân tích cú pháp tệp đầu vào trong một hàm python. Tuy nhiên, sau khi được tạo, nó vẫn giữ nguyên cho lần chạy đó.

Tôi đang sử dụng cấu trúc dữ liệu này trong chức năng của mình.

Vì vậy, nếu tệp thay đổi, lần tiếp theo ứng dụng này được chạy, nội dung của tệp sẽ khác và do đó nội dung của cấu trúc dữ liệu này sẽ khác nhưng định dạng sẽ giống nhau. Vì vậy, bạn thấy tôi trong chức năng của tôi, tôi không biết rằng yếu tố đầu tiên trong Apple là 'Mỹ' hay bất kỳ thứ gì khác nên tôi không thể trực tiếp sử dụng 'Mỹ' làm khóa.


2
Bạn có thể vui lòng cho một ví dụ về đầu ra mà bạn mong đợi?
Björn Pollex

3
Bạn thực sự muốn làm gì với cấu trúc này? Và bạn có biết các phím của dict ('Apple' và 'Grapes' trong ví dụ của bạn) không? Hay bạn chỉ biết rằng bạn sẽ nhận được một mệnh lệnh của các phái?
juanchopanza

6
Đừng gọi từ điển của bạn dict. Từ 'dict' đã là một từ khóa trong Python. Sử dụng một cái gì đó khác, như mydict.
Rick ủng hộ Monica.

Lưu ý: Câu hỏi này là về việc truy cập các phần tử dict theo chỉ mục , điều này không có ý nghĩa gì vì các phần không có thứ tự. Đối với câu hỏi về cách truy cập các phần tử trong một mệnh lệnh lồng nhau, hãy xem Python - truy cập các giá trị được lồng trong từ điển .
Aran-Fey

@ Aran-Fey: những thứ không có thứ tự có trật tự nội tại. Unordered! = Không có thứ tự.
Jamie Marshall

Câu trả lời:


122

Cho rằng nó là một từ điển, bạn truy cập nó bằng cách sử dụng các phím. Lấy từ điển được lưu trữ trong "Apple", hãy làm như sau:

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

Và có bao nhiêu người trong số họ là người Mỹ (16), hãy làm như thế này:

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

9
Làm thế nào người ta có thể làm điều này một cách linh động mà không cần biết độ sâu của các phần tử?
Ethan Bierlein

3
Bạn muốn biết chính xác điều gì? Bạn có thể lấy các khóa của từ điển .keys()để có thể truy cập động.
Morten Kristensen

3
Chẳng hạn như, nếu bạn có một từ điển có độ sâu không xác định, ví dụ, một từ điển lồng nhau và bạn có phần tử "n"ở độ sâu không xác định, được lưu trữ trong một phần tử không xác định.
Ethan Bierlein

1
Đó là một câu hỏi rất rộng. Với cấu trúc dữ liệu của bạn, sau đó bạn sẽ viết một hàm hoặc lớp để xử lý nó một cách thích hợp. Có lẽ bạn có thể cung cấp một chìa khóa và một chiến lược để cố gắng tìm ra chìa khóa.
Morten Kristensen

1
@EthanBierlein sử dụng: 'cho khóa, giá trị trong dictionary.iteritems ()' được tiếp cận với cả hai quan trọng và giá trị
Danius

25

Nếu câu hỏi là, nếu tôi biết rằng tôi có một câu mệnh đề trong đó có 'Apple' là một loại trái cây và 'American' là một loại táo, tôi sẽ sử dụng:

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


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

như những người khác đề xuất. Thay vào đó, nếu câu hỏi là, bạn không biết liệu 'Apple' như một loại trái cây và 'Mỹ' là một loại 'Apple' có tồn tại hay không khi bạn đọc một tệp tùy ý vào cấu trúc dữ liệu dict of dict, bạn có thể làm như sau:

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

hoặc tốt hơn nữa để bạn không cần lặp lại toàn bộ chính tả một cách không cần thiết nếu bạn biết rằng chỉ Apple mới có loại American:

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

Trong tất cả những trường hợp này, không quan trọng thứ tự các từ điển thực sự lưu các mục từ. Nếu bạn thực sự lo lắng về đơn đặt hàng, thì bạn có thể cân nhắc sử dụng OrderedDict:

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


20

Khi tôi nhận thấy mô tả của bạn, bạn chỉ biết rằng trình phân tích cú pháp của bạn sẽ cung cấp cho bạn một từ điển mà các giá trị của nó cũng là từ điển như sau:

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

Vì vậy, bạn phải lặp lại từ điển mẹ của mình. Nếu bạn muốn in ra hoặc truy cập tất cả các khóa từ điển đầu tiên trong sampleDict.values()danh sách, bạn có thể sử dụng một cái gì đó như sau:

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

Nếu bạn chỉ muốn truy cập vào khóa đầu tiên của mục đầu tiên sampleDict.values(), điều này có thể hữu ích:

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

Nếu bạn sử dụng ví dụ bạn đưa ra trong câu hỏi, ý tôi là:

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

Đầu ra cho mã đầu tiên là:

American
Indian

Và đầu ra cho mã thứ hai là:

American

10

Như một phần thưởng, tôi muốn đưa ra một loại giải pháp khác cho vấn đề của bạn. Dường như bạn đang xử lý các từ điển lồng nhau, điều này thường rất tẻ nhạt, đặc biệt là khi bạn phải kiểm tra sự tồn tại của khóa bên trong.

Có một số thư viện thú vị liên quan đến điều này trên pypi, đây là một tìm kiếm nhanh cho bạn.

Trong trường hợp cụ thể của bạn, dict_digger có vẻ phù hợp.

>>> 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

Bạn có thể sử dụng dict['Apple'].keys()[0]để lấy khóa đầu tiên trong Appletừ điển, nhưng không có gì đảm bảo rằng nó sẽ có American. Thứ tự của các khóa trong từ điển có thể thay đổi tùy thuộc vào nội dung của từ điển và thứ tự các khóa được thêm vào.


trừ khi bạn sử dụng OrderedDicttrong collectionsthư viện
Escachator

7

Tôi biết điều này đã 8 năm tuổi, nhưng dường như không ai thực sự đọc và trả lời câu hỏi.

Bạn có thể gọi .values ​​() trên một dict để nhận danh sách các đường bên trong và do đó truy cập chúng theo chỉ mục.

>>> 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
thú vị, tôi đã thử điều này và nhận được 'dict_values' object does not support indexing . Đoán câu trả lời này cần cập nhật vì bạn cần phải bọc dict_values ​​để khôi phục danh sách
Yuca

1
@Yucca - Bạn nói đúng, tôi đã không kiểm tra mã của mình. Câu trả lời đã được cập nhật
Jamie Marshall



0

Rất ít người xuất hiện, mặc dù có nhiều câu trả lời cho câu hỏi này, đã chỉ ra rằng từ điển là các ánh xạ không có thứ tự, và do đó (cho đến khi có được thứ tự chèn với Python 3.7), ý tưởng về mục từ "đầu tiên" trong từ điển được thực hiện theo nghĩa đen vô nghĩa. Và thậm chí một OrderedDictchỉ có thể được truy cập bằng chỉ mục số bằng cách sử dụng các độ xấu như mydict[mydict.keys()[0]](chỉ trong Python 2, vì trong Python 3 keys()là một trình lặp không thể thay thế.)

Từ 3.7 trở đi và trong thực tế cũng vậy trong 3.6 - hành vi mới đã được giới thiệu sau đó, nhưng không được bao gồm như một phần của đặc tả ngôn ngữ cho đến 3.7 - lặp lại các khóa, giá trị hoặc mục của một mệnh lệnh (và, tôi tin rằng, đặt cũng) sẽ mang lại các đối tượng được chèn gần đây nhất trước tiên. Vẫn không có cách nào đơn giản để truy cập chúng bằng chỉ số chèn.

Đối với câu hỏi về việc chọn và "định dạng" các mục, nếu bạn biết khóa bạn muốn truy xuất trong từ điển, bạn thường sử dụng khóa đó như một chỉ số phụ để lấy nó (my_var = mydict['Apple'] ).

Nếu bạn thực sự muốn có thể lập chỉ mục các mục theo số mục nhập (bỏ qua thực tế là số của mục nhập cụ thể sẽ thay đổi khi thực hiện chèn) thì cấu trúc thích hợp có thể là danh sách các bộ gồm hai phần tử. Thay vì

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

bạn có thể sử dụng:

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

Theo chế độ này, mục nhập đầu tiên mylist[0]ở dạng danh sách kết thúc cổ điển và giá trị của nó là ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). Bạn có thể lặp lại toàn bộ danh sách như sau:

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

nhưng nếu bạn biết bạn đang tìm chìa khóa "Apple", tại sao bạn không sử dụng một câu lệnh thay thế?

Bạn có thể giới thiệu một cấp độ điều hướng bổ sung bằng cách lưu vào bộ đệm danh sách các khóa, nhưng sự phức tạp của việc giữ hai cấu trúc dữ liệu đồng bộ hóa chắc chắn sẽ làm tăng thêm độ phức tạp cho mã của bạn.


0

Với chức năng nhỏ sau, việc đào từ điển hình cây trở nên khá dễ dàng:

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

Bây giờ, dig(mydict, "Apple.Mexican")trả về 10, trong khi dig(mydict, "Grape")tạo ra cây con {'Arabian':'25','Indian':'20'}. Nếu khóa không có trong từ điển, digtrả vềNone .

Lưu ý rằng bạn có thể dễ dàng thay đổi (hoặc thậm chí tham số hóa) ký tự phân cách từ '.' thành '/', '|' Vân vân.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.