Jak indeksować do słownika?


101

Mam słownik poniżej:

colors = {
    "blue" : "5",
    "red" : "6",
    "yellow" : "8",
}

Jak zindeksować pierwszy wpis w słowniku?

colors[0]zwróci z KeyErroroczywistych powodów.


4
Co oznacza „pierwszy”? Słowniki nie mają uporządkowania.
S.Lott

4
Słowniki są teraz wstawiane w kolejności od wersji Python 3.7 Sprawdź to: stackoverflow.com/questions/39980323/…
Nikita Alkhovik

Powiązane: Efektywny
dostęp

1
@ S.Lott Założę się, że nie zapytałby, gdyby wiedział, że są nieuporządkowane :).
user7778287

Odpowiedzi:


119

Słowniki są nieuporządkowane w wersjach Pythona do Pythona 3.6 włącznie. Jeśli nie zależy Ci na kolejności wpisów i mimo wszystko chcesz uzyskać dostęp do kluczy lub wartości według indeksu, możesz użyć d.keys()[i]i d.values()[i]lub d.items()[i]. (Zwróć uwagę, że te metody tworzą listę wszystkich kluczy, wartości lub elementów w Pythonie 2.x. Jeśli więc potrzebujesz ich więcej niż raz, przechowuj listę w zmiennej, aby poprawić wydajność).

Jeśli zależy Ci na kolejności wpisów, zaczynając od Pythona 2.7 możesz użyć collections.OrderedDict. Lub użyj listy par

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

jeśli nie potrzebujesz dostępu za pomocą klucza. (Nawiasem mówiąc, dlaczego twoje ciągi liczbowe?)

W Pythonie 3.7 normalne słowniki są uporządkowane, więc nie musisz ich OrderedDictjuż używać (ale nadal możesz - to w zasadzie ten sam typ). Implementacja CPythona w Pythonie 3.6 już zawierała tę zmianę, ale ponieważ nie jest to część specyfikacji języka, nie można na niej polegać w Pythonie 3.6.


3
W Pythonie 2 użyj d.iterkeys().next()zamiast, d.keys()[0]aby sprawdzić jeden z kluczy bez usuwania go. Jeśli słownik jest ogromny, będzie miał duży wpływ na wydajność. To samo dotyczy wartości i przedmiotów. W Pythonie 2.7 możesz także używać obiektów widoku dict
simleo

47
W Pythonie 3 wywołania te zwracają raczej widok niż aktualną listę, więc powinieneś zawinąć je w wywołanie list (), w przeciwnym razie zobaczysz: „TypeError: obiekt 'dict_values' nie obsługuje indeksowania”. Zobacz to pytanie SO: stackoverflow.com/questions/17431638/…
stifin

4
Tylko mała poprawka: nie można indeksować elementów (), przynajmniej nie w Pythonie 3.
John Strong

2
Ta odpowiedź jest nieaktualna dla Pythona 3.6+, zobacz odpowiedź @Pasha poniżej.
hans

1
@hans Ta odpowiedź jest nieaktualna dla Pythona 3.7, ale nie dla Pythona 3.6, ponieważ chroniąca porządek natura słowników jest szczegółem implementacji CPythona w tej wersji Pythona, a nie oficjalną częścią języka. Zaktualizuję odpowiednio tę odpowiedź.
Sven Marnach

123

Jeśli ktoś nadal patrzy na to pytanie, obecnie przyjęta odpowiedź jest już nieaktualna:

Od wersji Python 3.7 * słowniki zachowują kolejność , to znaczy, że teraz zachowują się dokładnie tak, jak collections.OrderedDictkiedyś. Niestety, nadal nie ma dedykowanej metody indeksowania do keys()/ values()ze słownika, więc pobranie pierwszego klucza / wartości w słowniku można wykonać w następujący sposób

first_key = list(colors)[0]
first_val = list(colors.values())[0]

lub alternatywnie (pozwala to uniknąć tworzenia instancji widoku kluczy w liście):

def get_first_key(dictionary):
    for key in dictionary:
        return key
    raise IndexError

first_key = get_first_key(colors)
first_val = colors[first_key]

Jeśli potrzebujesz n-tego klucza, to podobnie

def get_nth_key(dictionary, n=0):
    if n < 0:
        n += len(dictionary)
    for i, key in enumerate(dictionary.keys()):
        if i == n:
            return key
    raise IndexError("dictionary index out of range") 

(* CPython 3.6 już zawierał dykty zamówione, ale był to tylko szczegół implementacji. Specyfikacja języka obejmuje dykty zamówione od wersji 3.7).


Czy mogę podać link do odpowiedniej dokumentacji?
Amir Afianian

3

Zajmowanie się elementem słownika jest jak siedzenie na osiołku i radość z jazdy.

Z reguły w Pythonie SŁOWNIK jest uporządkowany

Jeśli jest

dic = {1: "a", 2: "aa", 3: "aaa"}

Teraz przypuśćmy, że jeśli pójdę tak dic[10] = "b", to nie będzie tak dodawać zawsze

dic = {1:"a",2:"aa",3:"aaa",10:"b"}

Może tak

dic = {1: "a", 2: "aa", 3: "aaa", 10: "b"}

Lub

dic = {1: "a", 2: "aa", 10: "b", 3: "aaa"}

Lub

dic = {1: "a", 10: "b", 2: "aa", 3: "aaa"}

Albo jakąkolwiek taką kombinację.

Zatem praktyczna zasada jest taka, że SŁOWNIK nie ma porządku !


to jest bardzo trudne ... Podoba mi się!
Alex Liu 33214


2

w rzeczywistości znalazłem nowatorskie rozwiązanie, które naprawdę mi pomogło.Jeśli jesteś szczególnie zainteresowany indeksem określonej wartości na liście lub zestawie danych, możesz po prostu ustawić wartość słownika na ten indeks !:

Tylko patrz:

list = ['a', 'b', 'c']
dictionary = {}
counter = 0
for i in list:
   dictionary[i] = counter
   counter += 1

print(dictionary) # dictionary = {'a':0, 'b':1, 'c':2}

Teraz dzięki mocy hashmap możesz ciągnąć indeks swoich wpisów w stałym czasie (czyli o wiele szybciej)


1

och, to jest trudne. Zasadniczo masz tutaj dwie wartości dla każdego elementu. Następnie próbujesz zadzwonić do nich, podając numer jako klucz. Niestety, jedna z Twoich wartości jest już ustawiona jako klucz!

Spróbuj tego:

colors = {1: ["blue", "5"], 2: ["red", "6"], 3: ["yellow", "8"]}

Teraz możesz wywoływać klucze według numerów, tak jakby były indeksowane jak lista. Możesz również odwołać się do koloru i numeru, podając ich pozycję na liście.

Na przykład,

colors[1][0]
// returns 'blue'

colors[3][1]
// returns '8'

Oczywiście będziesz musiał wymyślić inny sposób śledzenia lokalizacji każdego koloru. Może możesz mieć inny słownik, który przechowuje klucz każdego koloru jako jego wartość.

colors_key = {'blue': 1, 'red': 6, 'yllow': 8}

Wtedy będziesz mógł również sprawdzić klucz kolorów, jeśli zajdzie taka potrzeba.

colors [colors_key ['blue']] [0] zwróci wartość 'blue'

Coś w tym stylu.

A potem, kiedy już to robisz, możesz stworzyć dyktando z wartościami liczbowymi jako kluczami, aby zawsze móc ich użyć do wyszukania swoich kolorów, wiesz, jeśli potrzebujesz.

wartości = {5: [1, 'niebieski'], 6: [2, 'czerwony'], 8: [3, 'żółty']}

Następnie (colors [colors_key [values ​​[5] [1]]] [0]) zwróci wartość „blue”.

Lub możesz użyć listy list.

Powodzenia!


0

Nie możesz, ponieważ dictjest nieuporządkowany. możesz użyć, .popitem()aby uzyskać dowolny przedmiot, ale spowoduje to usunięcie go z dyktowania.


next(iter(d.items()))( .iteritems()w Pythonie 2) daje również dowolny element (to samo w moich testach, co ma sens, ponieważ popitem można zaimplementować za pomocą tego), ale nie usunie elementu.
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.