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