Uzyskaj dostęp do dowolnego elementu w słowniku w Pythonie


506

Jeśli a mydictnie jest puste, uzyskuję dostęp do dowolnego elementu jako:

mydict[mydict.keys()[0]]

Czy jest na to lepszy sposób?


3
To, co powiedział ... To jest naprawdę ważne pytanie tylko wtedy, gdy jest tylko jeden element w dykcie, lub nie obchodzi Cię, który z nich odzyskasz.
królewski

5
Tak, po prostu muszę uzyskać dostęp do dowolnego elementu słownika, dlatego chcę uzyskać dostęp do pierwszego elementu.
Stan

2
@Stan: ale jak powiedział Greg, w dyktandzie nie ma określonego „pierwszego” elementu. więc może powinieneś zmienić swoje pytanie, żeby było jasne
tdihp

10
Myślę, że to ważne pytanie. Jeśli potrzebujesz dostępu do dowolnego elementu i masz pewność, że dyktat nie jest pusty, dobrym pomysłem może być poproszenie o „pierwszy”, ponieważ liczba elementów może nie być znana.
kap

7
@MichaelScheper Trzeba obsady do listy: list(mydict.keys())[0].
Daniel Moskovich,

Odpowiedzi:


600

W Pythonie 3, nieniszczący i iteracyjny:

next(iter(mydict.values()))

W Pythonie 2, nieniszczący i iteracyjny:

mydict.itervalues().next()

Jeśli chcesz, aby działał zarówno w Pythonie 2, jak i 3, możesz użyć sixpakietu:

six.next(six.itervalues(mydict))

choć w tym momencie jest to dość tajemnicze i wolałbym twój kod.

Jeśli chcesz usunąć dowolny element, wykonaj:

key, value = mydict.popitem()

Zauważ, że „pierwszy” może nie być tutaj odpowiednim terminem, ponieważ dictnie jest uporządkowanym typem w Pythonie <3.6. Python 3.6+ dictssą zamawiane.


35
Nie masz na myśli dict.iterkeys().next()?
John Machin

12
@John Machin: Cóż, pytanie wydaje się mieć dostęp do wartości związanej z pierwszym kluczem, więc tak też robię w odpowiedzi.
doublelep

5
wygląda to lepiej: dict.values().__iter__().__next__():)
Witalij Zdanewicz

17
denerwujące jest to, że dict.keys () nie jest bezpośrednio iterowalny.
semiomant

3
dla nieniszczącego popitem możesz zrobić (płytką) kopię:key, value = dict(d).popitem()
Pelle

139

Jeśli potrzebujesz tylko dostępu do jednego elementu (jest to pierwszy przypadek, ponieważ dyktaty nie gwarantują zamówienia), możesz to po prostu zrobić w Pythonie 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

Należy pamiętać, że (według mojej najlepszej wiedzy) Python nie gwarantuje, że 2 kolejne wywołania którejkolwiek z tych metod zwrócą listę z tą samą kolejnością. Nie jest to obsługiwane w Python3.

w Pythonie 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
Działa to tylko w Pythonie 2.x, dla wersji 3.x musisz użyćlist(my_dict.keys())[0]
alldayremix

6
Jaka to jest klasa złożoności? Z pewnością list(my_dict.keys())[0]nie jest leniwy?
Jewgienij Siergiejew

1
Aby wyjaśnić, co @alldayremix oznaczało dla tego komentarza, w pythonie 3.x wyniki my_dict.function () nie obsługują indeksowania, dlatego najpierw musimy przekonwertować go na listę, a następnie użyć indeksu [0]
Noki

57

W python3 sposób:

dict.keys() 

zwróć wartość typu: dict_keys (), otrzymamy błąd, gdy otrzymamy 1. element klucza dict w ten sposób:

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

Na koniec przekonwertowałem dict.keys () na list @ 1st i uzyskałem 1. członka metodą łączenia list:

list(dict.keys())[0]

Jest to najłatwiejsze rozwiązanie i działa zarówno w python2, jak i python3.
mattmilten

Za moje pieniądze. Mówię, że ta odpowiedź jest najbardziej intuicyjna
Thomas Valadez

Tak, ale to nie odpowiada na pytanie PO, czyli jak uzyskać WARTOŚCI, a nie klucze.
Mike Williamson

1
@MikeWilliamson mam nadzieję, że większość czytelników będzie wiedziała, jak uzyskać odpowiednią wartość, biorąc pod uwagę klucz, ze słownika python.
eryczny

5
Aby uzyskać dowolny przedmiot, a nie dowolny klucz, możesz to zrobić analogicznie list(dict.values())[0].
jhin

24

zdobyć klucz

next(iter(mydict))

uzyskać wartość

next(iter(mydict.values()))

zdobyć oba

next(iter(mydict.items())) # or next(iter(mydict.viewitems())) in python 2

Pierwsze dwa to Python 2 i 3. Ostatnie dwa są leniwe w Pythonie 3, ale nie w Pythonie 2.


16

Jak wspomniano inni, nie ma „pierwszego elementu”, ponieważ słowniki nie mają gwarantowanej kolejności (są implementowane jako tabele skrótów). Jeśli chcesz na przykład wartość odpowiadającą najmniejszemu kluczowi, thedict[min(thedict)]zrobisz to. Jeśli zależy ci na kolejności, w jakiej klucze zostały wstawione, tzn. „Pierwszy” oznacza „wstawiony najwcześniej”, to w Pythonie 3.1 możesz używać kolekcji.OrDERDict , który jest również w nadchodzącym Pythonie 2.7; w przypadku starszych wersji Pythona pobierz, zainstaluj i użyj zamówionego backportu dict (2.4 i nowszych), który można znaleźć tutaj .

Python 3.7 Teraz dyktanda są uporządkowane przy wstawianiu.


11

Co powiesz na to. Nie wspomniano tu jeszcze.

py 2 i 3

a = {"a":2,"b":3}
a[list(a)[0]] # the first element is here
>>> 2

5
dict.values()zwraca widok, więc powinno być O (1). list(a)zwraca nową listę, więc byłoby O (n).
boycy

Wygląda też na to, że nie działa w python2, jeśli a = {"a": {"1"}}
qasimzee

11

Zignorowanie problemów związanych z kolejnością nagrań może być lepsze:

next(dict.itervalues())

W ten sposób unikamy wyszukiwania elementów i generowania listy kluczy, których nie używamy.

Python3

next(iter(dict.values()))

2
wartości () utworzą kopię wszystkich wartości (podobnie jak klucze () dla kluczy), więc spowoduje to wiele operacji O (n ^ 2).
Glenn Maynard

Więc będzie wersja OP? Zmienię to, aby użyć iteratora.
Matt Joiner

4
To jest tylko Python 2. W przypadku Python 3 musimy next(iter(dict.values()))uzyskać ten sam wynik bez tworzenia listy.
kap


2

Zawsze możesz zrobić:

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

To da ci konsekwentnie posortowany (w odniesieniu do wbudowanego .hash () chyba) zestaw kluczy, które możesz przetwarzać, jeśli sortowanie ma dla ciebie jakieś znaczenie. Oznacza to, że na przykład typy liczbowe są sortowane konsekwentnie, nawet jeśli rozszerzysz słownik.

PRZYKŁAD

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

Pamiętaj, że słownik jest sortowany po wydrukowaniu. Ale zestaw kluczy to w zasadzie skrót!


2

Zarówno dla Python 2, jak i 3:

import six

six.next(six.itervalues(d))

To nie daje odpowiedzi na pytanie. Aby skrytykować lub poprosić autora o wyjaśnienia, zostaw komentarz pod postem.
Martin Tournoij

To dokładnie odpowiada na pytanie Is there any better way to do this?w skrócie.
oblalex

Ta odpowiedź została już udzielona dwukrotnie, z których jedna jest obecna na tej stronie od prawie 5 lat. To jest komentarz do innej odpowiedzi (jak w: oto jak poprawić odpowiedź, aby działała zarówno z Pythonem 2, jak i 3 ), a nie jako „nowa” odpowiedź jako taka. System recenzji SO automatycznie umieścił nieco nieprzydatną notatkę w tym przypadku ...
Martin Tournoij

Nie proszę pana. Dodałeś ten wariant do swojej 5-letniej odpowiedzi zaledwie 17 godzin temu, 1 godzinę po napisaniu tej odpowiedzi. Spróbuj użyć „znajdź” na tej stronie dla słowa „sześć”, a znajdziesz tylko 6 dopasowań tylko w tych 2 odpowiedziach. W każdym razie, czy ta odpowiedź naprawdę Cię niepokoi? Myślę, że może to pomóc innym ludziom w przyszłości i to jest OK. Więc o co chodzi?
oblalex

To dlatego, że IMHO ta odpowiedź powinna być przede wszystkim edycją tego postu. Bez edycji ludzie musieliby przewinąć kilka stron w dół, aby zobaczyć twoją odpowiedź; czy uważasz, że jest to bardziej przydatne niż edytowanie bardzo pozytywnej odpowiedzi, która jest prawie dokładnie taka sama jak twoja?
Martin Tournoij

0
first_key, *rest_keys = mydict

11
Dziękujemy za ten fragment kodu, który może zapewnić pewną ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie byłoby znacznie poprawić swoją długoterminową wartość pokazując dlaczego jest to dobre rozwiązanie problemu, a byłoby bardziej użyteczne dla czytelników przyszłości z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
Suraj Rao,

-1

Brak bibliotek zewnętrznych, działa zarówno w Pythonie 2.7, jak i 3.x:

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

W przypadku klucza aribtrary po prostu pomiń .values ​​()

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

-2

Podklasowanie dictjest jedną z metod, choć nieefektywną. Tutaj, jeśli podasz liczbę całkowitą, ona zwróci d[list(d)[n]], w przeciwnym razie uzyskaj dostęp do słownika zgodnie z oczekiwaniami:

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'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.