Bir sözlüğe nasıl dizin eklenir?


97

Aşağıda bir Sözlüğüm var:

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

Sözlükteki ilk girişi nasıl indekslerim?

colors[0]KeyErrorbariz nedenlerden dolayı bir dönecektir .


4
"İlk" ne anlama geliyor? Sözlüklerin sıralaması yoktur.
S.Lott

2
Sözlükler artık Python
3.7'den


1
@ S.Lott Bahse girerim sırasız olduklarını bilseydi sormazdı :).
user7778287

Yanıtlar:


113

Sözlükler, Python 3.6'ya kadar ve dahil olmak üzere Python sürümlerinde sıralanmamıştır. Eğer girişlerin sırasına önem ve yine endeksine göre anahtarları veya değerleri erişmek istemiyorsanız, kullanabileceğiniz d.keys()[i]ve d.values()[i]ya d.items()[i]. (Bu yöntemlerin Python 2.x'teki tüm anahtarların, değerlerin veya öğelerin bir listesini oluşturduğunu unutmayın. Bu nedenle, onlara birden çok kez ihtiyacınız varsa, performansı artırmak için listeyi bir değişkende saklayın.)

Girişlerin sırasını önemsiyorsanız, Python 2.7 ile başlayabilirsiniz collections.OrderedDict. Veya bir çift listesi kullanın

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

anahtarla erişime ihtiyacınız yoksa. (Numaraların neden bu arada diziliyor?)

Python 3.7'de normal sözlükler sıralanır, bu yüzden OrderedDictartık kullanmanıza gerek yoktur (ama yine de yapabilirsiniz - temelde aynı türdür). Python 3.6'nın CPython uygulaması bu değişikliği zaten içeriyordu, ancak dil spesifikasyonunun bir parçası olmadığı için Python 3.6'da buna güvenemezsiniz.


2
Python 2'de, anahtarlardan birini çıkarmadan incelemek d.iterkeys().next()yerine kullanın d.keys()[0]. Sözlük çok büyükse performans açısından büyük fark yaratacaktır. Aynı şey değerler ve öğeler için de geçerlidir. Python 2.7'de ayrıca
dikte

44
Python 3'te, bu çağrılar gerçek bir liste yerine bir görünüm döndürür, bu nedenle onları bir list () çağrısına sarmalısınız, aksi takdirde şunu göreceksiniz: "TypeError: 'dict_values' nesnesi indekslemeyi desteklemiyor". Şu SO sorusuna bakın: stackoverflow.com/questions/17431638/…
stifin

3
Küçük bir düzeltme: öğeleri dizine ekleyemezsiniz (), en azından Python 3'te.
John Strong

1
Bu cevap python 3.6+ için geçerliliğini yitirmiştir, lütfen aşağıdaki @Pasha tarafından verilen cevaba bakın.
hans

1
@hans Bu yanıt Python 3.7 için güncel değil, ancak Python 3.6 için geçerli değil, çünkü sözlüklerin sırasını koruyan yapısı, söz konusu Python sürümünün CPython uygulamasının bir uygulama ayrıntısıdır, dilin resmi bir parçası değildir. Bu yanıtı uygun şekilde güncelleyeceğim.
Sven Marnach

115

Hala bu soruya bakan biri varsa, şu anda kabul edilen cevap artık güncel değil:

Python 3.7 * 'den beri sözlükler sırayı koruyor , yani artık tam olarak eskisi gibi davranıyorlar collections.OrderedDict. Ne yazık ki, sözlüğe keys()/ values()sözlüğe indekslemek için hala özel bir yöntem yoktur , bu nedenle sözlükteki ilk anahtar / değerin alınması

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

veya alternatif olarak (bu, anahtar görünümünün bir liste halinde somutlaştırılmasını önler):

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

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

n-Th anahtara ihtiyacınız varsa , benzer şekilde

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 zaten sıralı sözlükleri içeriyordu, ancak bu yalnızca bir uygulama ayrıntısıydı. Dil belirtimi, 3.7'den itibaren sıralı sözcükleri içerir.)


Lütfen ilgili belgelerin bağlantısını sağlayabilir misiniz?
Amir Afianian

3

Sözlüğün bir unsurunu ele almak, eşeğin üzerinde oturup yolculuğun tadını çıkarmak gibidir.

Python SÖZLÜĞÜ kuralına göre sırasızdır

Varsa

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

Şimdi farz et ki eğer böyle gidersem dic[10] = "b", her zaman böyle eklemeyecek

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

Gibi olabilir

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

Veya

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

Veya

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

Veya böyle bir kombinasyon.

Yani temel kural SÖZLÜK , düzensizdir !


bu çok ileriye dönük ... Bunu beğendim!
Alex Liu 33214

2

Sıralı bir sözlüğe ihtiyacınız varsa, odict kullanabilirsiniz .


odict anahtarlar (), değerler () veya öğeler () indekslemeyi desteklemediğini görür.
Konstantin

2

aslında bana gerçekten yardımcı olan yeni bir çözüm buldum, Özellikle bir listedeki veya veri kümesindeki belirli bir değerin indeksiyle ilgileniyorsanız, sözlüğün değerini bu İndeks'e ayarlayabilirsiniz !:

Sadece izle:

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}

Artık, hashmap'lerin gücüyle, girdilerinizi dizini sabit zamanda (yani çok daha hızlı) çekebilirsiniz.


1

oh, bu zor bir şey. Burada sahip olduğunuz şey, temel olarak, her öğe için iki değerdir. O zaman onları anahtar olarak bir numara ile aramaya çalışıyorsunuz. Ne yazık ki, değerlerinizden biri zaten anahtar olarak ayarlandı!

Bunu dene:

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

Artık anahtarları bir liste gibi indekslenmiş gibi numaraya göre çağırabilirsiniz. Renk ve numaraya listedeki konumlarına göre de başvurabilirsiniz.

Örneğin,

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

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

Elbette, her rengin hangi konumda olduğunu takip etmenin başka bir yolunu bulmanız gerekecek. Belki her rengin anahtarını değer olarak saklayan başka bir sözlüğe sahip olabilirsiniz.

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

Ardından, gerekirse renk anahtarına da bakabilirsiniz.

renkler [colours_key ['blue']] [0] 'blue' döndürecektir

Bunun gibi bir şey.

Ve sonra, siz oradayken, sayı değerleri anahtar olarak kullanarak bir dikte yapabilirsiniz, böylece bunları her zaman renklerinizi aramak için kullanabilirsiniz, bilirsiniz, ihtiyacınız olursa.

değerler = {5: [1, 'mavi'], 6: [2, 'kırmızı'], 8: [3, 'sarı']}

Daha sonra (renkler [renkler_anahtar [değerler [5] [1]]] [0]) 'mavi' döndürür.

Veya bir liste listesi kullanabilirsiniz.

İyi şanslar!


0

dictSırasız olduğu için yapamazsınız . .popitem()rastgele bir öğe almak için kullanabilirsiniz , ancak bu onu dikteden kaldıracaktır.


next(iter(d.items()))( .iteritems()Python 2'de) size rastgele bir öğe de verir (benim testlerimde de aynısı, popitem bunu kullanarak uygulanabileceğinden anlamlıdır) ancak öğeyi kaldırmaz.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.