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


507

Якщо а mydictне порожній, я отримую доступ до довільного елемента як:

mydict[mydict.keys()[0]]

Чи є кращий спосіб зробити це?


3
Що він сказав ... це справді справедливе питання, якщо в диктаті є лише один елемент, або вам все одно, який ви отримаєте назад.
королівська

5
Так, мені просто потрібно отримати доступ до будь-якого елементу дикту, тому я хочу отримати доступ до першого елемента.
Стен

2
@Stan: але, як сказав Грег, у дикті немає певного "першого" елемента. тож, можливо, вам слід змінити своє питання, просто щоб було зрозуміло
tdihp

10
Я думаю, що це питання справедливе. Якщо вам потрібно отримати доступ до довільного елемента, і ви впевнені, що дикт не порожній, можливо, буде корисно запитати "першого", оскільки кількість елементів може бути невідома.
кап

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
для неруйнівного попітему ви можете зробити (неглибоку) копію: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 не гарантує, що два послідовних дзвінки на будь-який із цих методів повернуть список із тим самим замовленням. Це не підтримується з 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]
Noki

57

У python3, спосіб:

dict.keys() 

повернути значення типу: dict_keys (), ми отримаємо помилку, коли отримаємо 1-го члена ключів dict таким чином:

dict.keys()[0]
TypeError: 'dict_keys' object does not support indexing

Нарешті, я перетворюю dict.keys () у список @ 1st та отримую 1-го члена за методом списку сплайсів:

list(dict.keys())[0]

Це найпростіше рішення і працює як у python2, так і в python3.
mattmilten

За мої гроші. Я кажу, що ця відповідь найінтуїтивніша
Томас Валадес

Так, але це не відповідає на питання ОП, що полягає в тому, як дістатися до ЦІННОСТІ, а не до клавіш.
Майк Вільямсон

1
@MikeWilliamson, сподіваємось, більшість читачів знає, як отримати відповідне значення, задане ключем, з диктану пітона.
eric

5
Щоб отримати довільний предмет, а не довільний ключ, ви можете аналогічно зробити list(dict.values())[0].
jhin

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 завантажте, встановіть і використовуйте впорядкований репортаж (2.4 і пізніші версії), який ви можете знайти тут .

Python 3.7 Тепер дикти впорядковані.


11

Як щодо цього. Тут ще не згадується.

py 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
Значення () зроблять копію всіх значень (як і ключі () для ключів), тому це зробить багато операцій O (n ^ 2).
Гленн Мейнард

Так буде версія OPs? Я зміню це, щоб потім використовувати ітератор.
Метт Столяр

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?коротко.
oblalex

Цю відповідь давали вже двічі, одна з яких на цьому сайті вже майже 5 років. Це коментар до іншої відповіді (як у: ось як покращити відповідь, щоб вона працювала як із Python 2, так і з 3 ), а не "новою" відповіддю як такою. Система рецензування SO автоматично помістила дещо корисну примітку в цьому випадку ...
Мартін Турной

Ні, сер. Цей варіант ви додали до своєї відповіді за 5 років лише 17 годин тому, через 1 годину після того, як я написав цю відповідь. Спробуйте використати "знайти" на цій сторінці для слова "шість", і ви знайдете лише 6 відповідностей лише у цих 2 відповідях. У будь-якому випадку, ця відповідь насправді вас турбує? Я думаю, що це може допомогти іншим людям у майбутньому, і це нормально. Отже, яка угода?
oblalex

Це тому, що IMHO ця відповідь повинна була в першу чергу редагувати цю посаду. Без редагування люди повинні будуть прокручувати ряд сторінок вниз, щоб побачити вашу відповідь; чи вважаєте ви, що це корисніше, ніж редагування високообоснованої відповіді, яка майже точно така ж, як і ваша?
Мартін Турноїй

0
first_key, *rest_keys = mydict

11
Дякуємо за цей фрагмент коду, який може надати деяку обмежену, негайну допомогу. Належне пояснення було б значно поліпшити свою довгострокову цінність , показуючи , чому це хороше рішення проблеми, і зробить його більш корисним для читачів майбутніх з іншими подібними питаннями. Будь ласка , змініть свій відповідь , щоб додати деякі пояснення, в тому числі припущень , які ви зробили.
Suraj Rao

-1

Немає зовнішніх бібліотек, працює як на Python 2.7, так і на 3.x:

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

Для атрибутивного ключа просто залиште .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.