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?

Stan
źródło
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.

doublelep
źródło
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
swK
źródło
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]
Xb74Dkjb
źródło
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.

maxbellec
źródło
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.

Alex Martelli
źródło
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
animaacija
źródło
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()))
Matt Joiner
źródło
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
6

W python3

list(dict.values())[0]
Oleg Matei
źródło
4
Co się stanie, jeśli słownik zawiera miliard pozycji? :)
Fábio Dias
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!

Philipp Meier
źródło
2

Zarówno dla Python 2, jak i 3:

import six

six.next(six.itervalues(d))
oblalex
źródło
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
użytkownik1994083
źródło
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'
Thomas Browne
źródło
-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'
jpp
źródło