Доступ к произвольному элементу в словаре в 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заказаны.


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

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]

Это самое простое решение, которое работает как в 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.


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

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()))получить тот же результат без создания списка.
Кап


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

Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под своим постом.
Мартин Турной

Это точно отвечает на вопрос Is there any better way to do this?вкратце.
обласк

Этот ответ был дан уже дважды, один из которых был на этом сайте почти 5 лет. Это комментарий к другому ответу (как в: вот как улучшить ответ, чтобы он работал как с Python 2 и 3 ), а не как «новый» ответ как таковой. Система обзора SO автоматически разместила несколько бесполезную заметку в этом случае ...
Мартин Турной

Нет, сэр. Вы добавили этот вариант в свой пятилетний ответ всего 17 часов назад, через 1 час после того, как я написал этот ответ. Попробуйте использовать «найти» на этой странице для слова «шесть», и вы найдете только 6 совпадений только в этих 2 ответах. Во всяком случае, этот ответ действительно беспокоит вас? Я думаю, что это может помочь другим людям в будущем, и это нормально. Так в чем же дело?
обласк

Это потому, что ИМХО этот ответ должен был быть редактированием этого поста. Без редактирования люди должны были бы прокрутить несколько страниц вниз, чтобы увидеть ваш ответ; Считаете ли вы, что это более полезно, чем редактирование ответа с высоким голосом, который почти точно такой же, как ваш?
Мартин Турной

0
first_key, *rest_keys = mydict

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'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.