Как индексировать в словарь?

97

У меня есть словарь ниже:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

Как мне проиндексировать первую запись в словаре?

colors[0]вернет KeyErrorпо понятным причинам.

Harpal
источник
4
Что значит «первый»? Словари не упорядочены.
S.Lott
2
Словари теперь упорядочены по вставке, начиная с Python 3.7. Проверьте это: stackoverflow.com/questions/39980323/…
Никита Альховик 07
Связанный: Эффективный
доступ
1
@ S.Lott Держу пари, он бы не спросил, знал ли он, что они неупорядочены :).
user7778287

Ответы:

113

Словари неупорядочены в версиях Python до Python 3.6 включительно. Если вам не важен порядок записей и вы все равно хотите получить доступ к ключам или значениям по индексу, вы можете использовать d.keys()[i]и d.values()[i]или d.items()[i]. (Обратите внимание, что эти методы создают список всех ключей, значений или элементов в Python 2.x. Поэтому, если они вам нужны более одного раза, сохраните список в переменной для повышения производительности.)

Если вам важен порядок записей, начиная с Python 2.7 вы можете использовать collections.OrderedDict. Или используйте список пар

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

если вам не нужен доступ по ключу. (Кстати, почему ваши числа - это строки?)

В Python 3.7 обычные словари упорядочены, поэтому вам больше не нужно их использовать OrderedDict(но вы все равно можете - это в основном тот же тип). Реализация Python 3.6 в CPython уже включала это изменение, но поскольку оно не является частью спецификации языка, вы не можете полагаться на него в Python 3.6.

Свен Марнах
источник
2
В Python 2 используйте d.iterkeys().next()вместо, d.keys()[0]чтобы проверить один из ключей, не удаляя его. Если словарь большой, это будет иметь большое значение с точки зрения производительности. То же самое касается ценностей и предметов. В Python 2.7 вы также можете использовать объекты dict view
simleo
44
В Python 3 эти вызовы возвращают представление, а не фактический список, поэтому вы должны заключить их в вызов list (), иначе вы увидите: «TypeError: объект 'dict_values' не поддерживает индексацию». См. Этот вопрос SO: stackoverflow.com/questions/17431638/…
stifin
3
Небольшая поправка: вы не можете индексировать items (), по крайней мере, в Python 3.
Джон Стронг
1
Этот ответ устарел для python 3.6+, см. Ответ @Pasha ниже.
hans
1
@hans Этот ответ устарел для Python 3.7, но не для Python 3.6, поскольку сохраняющий порядок характер словарей является деталью реализации CPython-реализации этой версии Python, а не официальной частью языка. Я обновлю этот ответ соответственно.
Свен Марнах
115

Если кто-то все еще смотрит на этот вопрос, принятый в настоящее время ответ уже устарел:

Начиная с Python 3.7 * словари сохраняют порядок , то есть теперь они ведут себя точно так же, как collections.OrderedDictраньше. К сожалению, до сих пор нет специального метода для индексации в keys()/ values()из словаря, поэтому получить первый ключ / значение в словаре можно как

first_key = list(colors)[0]
first_val = list(colors.values())[0]

или альтернативно (это позволяет избежать создания экземпляра представления ключей в списке):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

Если вам нужен n-й ключ, то аналогично

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

(* CPython 3.6 уже включал упорядоченные словари, но это была лишь деталь реализации. Спецификация языка включает упорядоченные словари, начиная с версии 3.7.)

Паша
источник
Не могли бы вы дать ссылку на соответствующую документацию?
Amir Afianian 08
3

Обращаться к элементу словаря - это все равно что сидеть на осле и наслаждаться поездкой.

Как правило, СЛОВАРЬ Python не имеет порядка

Если там есть

dic = {1: "a", 2: "aa", 3: "aaa"}

Теперь предположим, что если я пойду как dic[10] = "b", то он не будет всегда так добавлять

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

Это может быть похоже

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

Или

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

Или

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

Или любое такое сочетание.

Так что правило большого пальца - СЛОВАРЬ - беспорядочно !

Радж Дамани
источник
это очень прямолинейно ... Мне это нравится!
Alex Liu 33214,
2

Если вам нужен упорядоченный словарь, вы можете использовать odict .

Утку Зихниоглу
источник
odict не поддерживает индексацию в keys (), values ​​() или items ().
Константин
2

на самом деле я нашел новое решение, которое действительно помогло мне. Если вас особенно беспокоит индекс определенного значения в списке или наборе данных, вы можете просто установить значение словаря для этого индекса !:

Просто смотреть:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

Теперь с помощью хэш-карт вы можете индексировать свои записи за постоянное время (то есть намного быстрее)

пользователь3368835
источник
1

о, это сложно. То, что у вас здесь, в основном, - это два значения для каждого элемента. Затем вы пытаетесь позвонить им по номеру в качестве ключа. К сожалению, одно из ваших значений уже установлено в качестве ключа!

Попробуй это:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

Теперь вы можете вызывать ключи по номерам, как если бы они индексировались как список. Вы также можете указать цвет и номер по их положению в списке.

Например,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

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

colors_key = {'синий': 1, 'красный': 6, 'yllow': 8}

Затем вы также сможете найти ключ цветов, если вам нужно.

colors [colors_key ['blue']] [0] вернет 'синий'

Что-то такое.

А затем, пока вы это делаете, вы можете создать диктант с числовыми значениями в качестве ключей, чтобы вы всегда могли использовать их для поиска своих цветов, знаете ли, если вам нужно.

values ​​= {5: [1, 'синий'], 6: [2, 'красный'], 8: [3, 'желтый']}

Тогда (colors [colors_key [values ​​[5] [1]]] [0]) вернет «синий».

Или вы можете использовать список списков.

Удачи!

Годфрейлюк
источник
0

Вы не можете, так как dictэто неупорядочено. вы можете использовать .popitem()для получения произвольного элемента, но это удалит его из dict.

Игнасио Васкес-Абрамс
источник
next(iter(d.items()))( .iteritems()в Python 2) также дает вам произвольный элемент (то же самое в моих тестах, что имеет смысл, поскольку с его помощью можно реализовать popitem), но не удаляет элемент.