Доступ к произвольному элементу в словаре в Python

507

Если a mydictне пусто, я получаю доступ к произвольному элементу как:

mydict[mydict.keys()[0]]

Есть ли лучший способ сделать это?

Стан
источник
3
То, что он сказал ... это действительно правильный вопрос, если в диктанте есть только один элемент, или вам все равно, какой ответ вы получите.
королевский
5
Да, мне просто нужен доступ к любому элементу в dict, поэтому я хочу получить доступ к первому элементу.
Стан
2
@Stan: но, как сказал Грег, в dict нет определенного «первого» элемента. так что, возможно, вам следует изменить свой вопрос, просто чтобы прояснить
ситуацию
10
Я думаю, что это правильный вопрос. Если вам нужен доступ к произвольному элементу, и вы уверены, что dict не является пустым, может быть хорошей идеей попросить «первый», потому что количество элементов может быть неизвестно.
Кап
7
@MichaelScheper Вы должны преобразованный в списке: list(mydict.keys())[0].
Даниил Москович

Ответы:

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

Обратите внимание, что «first» может быть не подходящим термином, потому что dictэто не упорядоченный тип в Python <3.6. Python 3.6+ dictsзаказаны.

doublep
источник
35
Ты имеешь в виду dict.iterkeys().next()?
Джон Мачин
12
@John Machin: Ну, вопрос, похоже, касается значения, связанного с первым ключом, так что это то, что я делаю в ответе.
удвоить
5
это выглядит лучше: dict.values().__iter__().__next__():)
Виталий Зданевич
17
досадно, что dict.keys () не может быть напрямую повторен.
полуомант
3
для неразрушающего popitem вы можете сделать (мелкую) копию:key, value = dict(d).popitem()
Pelle
140

Если вам нужно получить доступ только к одному элементу (будучи первым случайно, поскольку диктовки не гарантируют порядок), вы можете просто сделать это в 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
SWK
источник
90
Это работает только в Python 2.x, для 3.x вы должны использоватьlist(my_dict.keys())[0]
alldayremix
6
Итак, что это за класс сложности? Конечно, list(my_dict.keys())[0]не ленивый?
Евгений Сергеев
1
Чтобы уточнить, что @alldayremix имел в виду под этим комментарием, результаты в python 3.x my_dict.function () не поддерживают индексирование, поэтому прежде всего мы должны преобразовать его в список, а затем использовать индекс [0].
Ноки
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]
Xb74Dkjb
источник
Это самое простое решение, которое работает как в python2, так и в python3.
Mattmilten
За мои деньги. Я говорю, что этот ответ самый интуитивный
Томас Валадес
Да, но это не отвечает на вопрос ОП, а именно, как получить ЗНАЧЕНИЯ, а не ключи.
Майк Уильямсон
1
@MikeWilliamson, надеюсь, большинство читателей знает, как получить соответствующее значение, заданное ключом, из запроса Python.
Эрик
5
Чтобы получить произвольный элемент, а не произвольный ключ, вы можете сделать это аналогичным образом list(dict.values())[0].
января
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.

maxbellec
источник
16

Как уже упоминалось, «первого элемента» не существует, поскольку словари не имеют гарантированного порядка (они реализованы в виде хеш-таблиц). Если вы хотите, например, значение, соответствующее наименьшему ключу, thedict[min(thedict)]будет делать это. Если вас волнует порядок, в котором ключи были вставлены, то есть «первым» вы подразумеваете «вставленный раньше», то в Python 3.1 вы можете использовать collection.OrderedDict , который также будет в готовящемся Python 2.7; для более старых версий Python загрузите, установите и используйте упорядоченный обратный порт dict (2.4 и более поздние версии), который вы можете найти здесь .

Python 3.7 Теперь дикты упорядочены по вставке.

Алекс Мартелли
источник
11

Как насчет этого. Здесь еще не упоминается.

пи 2 и 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2
animaacija
источник
5
dict.values()возвращает представление, поэтому должно быть O (1). list(a)возвращает новый список, поэтому будет O (n).
мальчик
Также кажется, что это не работает в python2, если a = {"a": {"1"}}
qasimzee
11

Не обращая внимания на вопросы, связанные с порядком выбора, это может быть лучше:

next(dict.itervalues())

Таким образом мы избегаем поиска элементов и генерируем список ключей, которые мы не используем.

python3

next(iter(dict.values()))
Мэтт Джойнер
источник
2
values ​​() создаст копию всех значений (как и keys () для ключей), поэтому будет выполнено много операций O (n ^ 2).
Гленн Мейнард
Так будет ли версия ОП? Я изменю это, чтобы использовать итератор тогда.
Мэтт Столяр
4
Это только Python 2. Для Python 3 нам нужно next(iter(dict.values()))получить тот же результат без создания списка.
Кап
6

В python3

list(dict.values())[0]
Олег Матей
источник
4
Что произойдет, если в словаре будет миллиард записей? :)
Фабио Диас
2

Вы всегда можете сделать:

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

Это даст вам последовательно отсортированный (относительно встроенного .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())

Обратите внимание, что словарь сортируется при печати. Но набор ключей по сути является хэш-картой!

Филипп Мейер
источник
2

Для Python 2 и 3:

import six

six.next(six.itervalues(d))
oblalex
источник
Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под своим постом.
Мартин Турной
Это точно отвечает на вопрос Is there any better way to do this?вкратце.
обласк
Этот ответ был дан уже дважды, один из которых был на этом сайте почти 5 лет. Это комментарий к другому ответу (как в: вот как улучшить ответ, чтобы он работал как с Python 2 и 3 ), а не как «новый» ответ как таковой. Система обзора SO автоматически разместила несколько бесполезную заметку в этом случае ...
Мартин Турной
Нет, сэр. Вы добавили этот вариант в свой пятилетний ответ всего 17 часов назад, через 1 час после того, как я написал этот ответ. Попробуйте использовать «найти» на этой странице для слова «шесть», и вы найдете только 6 совпадений только в этих 2 ответах. Во всяком случае, этот ответ действительно беспокоит вас? Я думаю, что это может помочь другим людям в будущем, и это нормально. Так в чем же дело?
обласк
Это потому, что ИМХО этот ответ должен был быть редактированием этого поста. Без редактирования люди должны были бы прокрутить несколько страниц вниз, чтобы увидеть ваш ответ; Считаете ли вы, что это более полезно, чем редактирование ответа с высоким голосом, который почти точно такой же, как ваш?
Мартин Турной
0
first_key, *rest_keys = mydict
user1994083
источник
11
Спасибо за этот фрагмент кода, который может оказать некоторую ограниченную, немедленную помощь. Надлежащее объяснение было бы значительно улучшить свою долгосрочную ценность , показывая , почему это хорошее решение проблемы, и сделает его более полезным для читателей будущих с другими подобными вопросами. Пожалуйста, измените свой ответ, чтобы добавить некоторые объяснения, в том числе предположения, которые вы сделали.
Сурадж Рао
-1

Нет внешних библиотек, работает на Python 2.7 и 3.x:

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

Для ключа aribtrary просто не указывайте .values ​​()

>>> 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'
JPP
источник