Доступ до елементів словника Python за індексом


118

Розгляньте на кшталт дикту

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

Як отримати доступ, наприклад, до певного елемента цього словника? наприклад, я хотів би надрукувати перший елемент після деякого форматування першого елемента Apple, який у нашому випадку є лише «американським»?

Додаткова інформація Вищевказана структура даних була створена шляхом аналізу вхідного файлу у функції python. Після створення, він залишається тим самим для цього запуску.

Я використовую цю структуру даних у своїй функції.

Отже, якщо файл змінюється, наступного разу, коли програма буде запущена, вміст файлу буде іншим, а значить, вміст цієї структури даних буде іншим, але формат буде однаковим. Отже, ви бачите, що я в своїй функції я не знаю, що перший елемент в Apple - "американський" або щось інше, тому я не можу безпосередньо використовувати "американський" як ключ.


2
Чи можете ви надати приклад очікуваного результату?
Бьорн Поллекс

3
Що ви насправді хочете зробити з цією структурою? А чи знаєте ви ключі дикту ("Apple" та "Виноград" у вашому прикладі)? Або ти лише знаєш, що отримаєш диктат?
juanchopanza

6
Не називайте свій словник dict. Слово "dict" - це вже ключове слово в Python. Використовуйте щось інше, наприклад mydict.
Рік підтримує Моніку

Примітка. Це питання стосується доступу елементів dict за допомогою індексу , що не має сенсу, оскільки дикти не упорядковані. Для запитання про доступ до елементів у вкладеному дікт див. Python - доступ до значень, вкладених у словники .
Аран-Фей

@ Аран-Фей: не упорядковані речі мають внутрішній порядок. Без замовлення! = Замовлення немає.
Джеймі Маршалл

Відповіді:


122

Враховуючи, що це словник, ви отримуєте доступ до нього за допомогою клавіш. Отримавши словник, що зберігається під "Apple", виконайте наступне:

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

І отримавши, скільки з них є американцями (16), зробіть так:

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

9
Як можна це зробити динамічно, не знаючи глибини елементів?
Етан Бірлен

3
Що саме ви хотіли б знати? Ви можете отримати ключі словника, .keys()щоб мати доступ до них динамічно.
Мортен Крістенсен

3
Як, наприклад, якщо у вас був словник невідомої глибини, наприклад, вкладений словник, і у вас є елемент "n"на невідомій глибині, який зберігається в невідомому елементі.
Етан Бірлен

1
Це дуже широке запитання. Зважаючи на вашу структуру даних, ви б потім написали функцію або клас, щоб обробляти її належним чином. Можливо, ви могли б надати ключ і стратегію спроби знайти ключ.
Мортен Крістенсен

1
@EthanBierlein використовує: "для ключа, значення в dictionary.iteritems ()", щоб мати доступ і до ключа, і до значення
danius

25

Якщо питання полягає в тому, якщо я знаю, що у мене діє дикта, що містить "Apple" як фрукт і "American" як тип яблука, я б використав:

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 має американський тип:

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 років, але, здається, ніхто насправді не читав і не відповідав на питання.

Ви можете зателефонувати .values ​​() на dict, щоб отримати список внутрішніх диктовок і таким чином отримати доступ до них за індексом.

>>> 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 - Ти був прав, я не перевіряв свій код. Відповідь оновлена
Джеймі Маршалл

4

Ви не можете покладатися на замовлення на словники. Але ви можете спробувати це:

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

Якщо ви хочете, щоб замовлення було збережено, ви можете скористатися цим: http://www.python.org/dev/peps/pep-0372/#ordered-dict-api


2

Простий приклад, щоб зрозуміти, як отримати доступ до елементів у словнику: -

Створіть словник

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 3keys() є ітератором, який не можна підписати.)

З 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]у класичній формі, доданій до списку, і його значення ('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", чому б ви просто не використали дикт замість цього?

Ви можете ввести додатковий рівень непрямості, кешуючи список клавіш, але складність збереження двох структур даних в синхронізації неминуче додасть складності вашого коду.


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'}. Якщо ключ не міститься у словнику, digповертаєтьсяNone .

Зауважте, що ви можете легко змінити (або навіть параметризувати) розділову таблицю з '.' до '/', '|' тощо.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.