Python sözlüğünün öğelerine indekse göre erişim


118

Gibi bir söz düşünün

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

Örneğin bu sözlüğün belirli bir öğesine nasıl erişebilirim? örneğin, ilk öğeyi Apple'ın ilk öğesini biçimlendirdikten sonra yazdırmak istiyorum ki bu bizim durumumuzda yalnızca "Amerikan"?

Ek bilgiler Yukarıdaki veri yapısı, bir python işlevindeki bir girdi dosyası ayrıştırılarak oluşturulmuştur. Ancak bir kez oluşturulduktan sonra o çalıştırma için aynı kalır.

Bu veri yapısını işlevimde kullanıyorum.

Dolayısıyla, dosya değişirse, bu uygulama bir dahaki sefer çalıştırıldığında dosyanın içeriği farklıdır ve bu nedenle bu veri yapısının içeriği farklı olacaktır, ancak format aynı olacaktır. Gördüğünüz gibi ben işlevimde Apple'daki ilk öğenin 'Amerikan' ya da başka bir şey olduğunu bilmiyorum, bu yüzden 'Amerikan'ı doğrudan anahtar olarak kullanamam.


2
Beklediğiniz çıktıya bir örnek verebilir misiniz?
Björn Pollex

3
Bu yapıyla aslında ne yapmak istiyorsunuz? Ve emrin anahtarlarını biliyor musunuz (örneğinizde 'Elma' ve 'Üzüm')? Yoksa sadece bir diktat alacağını mı biliyorsun?
juanchopanza

6
Sözlüğünü arama dict. 'Dict' kelimesi Python'da zaten bir anahtar kelimedir. Gibi başka bir şey kullanın mydict.
Rick, Monica'yı

Not: Bu soru, dikte öğelerine dizine göre erişimle ilgilidir , bu hiç mantıklı değil çünkü dikteler sıralanmamış. İç içe geçmiş bir diktteki öğelere erişme hakkında bir soru için, Python - sözlüklerin içine yerleştirilmiş değerlere erişme konusuna bakın .
Aran-Fey

@ Aran-Fey: sırasız şeylerin kendine özgü bir düzeni vardır. Sırasız! = Sipariş yok.
Jamie Marshall

Yanıtlar:


123

Bir sözlük olduğu için tuşlarını kullanarak ona erişirsiniz. Sözlüğü "Apple" altında saklamak için aşağıdakileri yapın:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

Ve kaçının Amerikalı olduğunu (16) öğrenmek, şöyle yapın:

>>> mydict["Apple"]["American"]
'16'

9
Elementlerin derinliğini bilmeden bunu dinamik olarak nasıl yapabiliriz?
Ethan Bierlein

3
Tam olarak ne bilmek istersiniz? Bir sözlüğün anahtarlarını .keys()kullanarak bunlara dinamik olarak erişebilirsiniz.
Morten Kristensen

3
Örneğin, derinliği bilinmeyen bir sözlüğünüz varsa, örneğin iç içe geçmiş bir sözlüğünüz varsa ve "n"bilinmeyen derinlikte, bilinmeyen bir öğede depolanan öğeniz varsa.
Ethan Bierlein

1
Bu çok geniş bir soru. Veri yapınız göz önüne alındığında, onu uygun şekilde işlemek için bir işlev veya sınıf yazarsınız. Belki de anahtarı bulmaya çalışmak için bir anahtar ve strateji sağlayabilirsiniz.
Morten Kristensen

1
@EthanBierlein şunu kullanın: 'anahtar için, dictionary.iteritems () içindeki değer' hem anahtara hem de değere erişmek için
danius

25

Eğer soru şu ise, meyve olarak 'Elma' ve bir elma türü olarak 'Amerikan' içeren bir diktim olduğunu bilirsem, şunu kullanırdım:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

diğerleri önerdiği gibi. Bunun yerine sorular soruyorsa, dikte veri yapınızın diktesine rastgele bir dosya okuduğunuzda bir meyve olarak 'Apple' ve bir tür 'Apple' olarak 'Amerikan' olup olmadığını bilmiyorsanız, aşağıdaki gibi bir şey yapabilirsiniz:

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

veya daha iyisi, yalnızca Apple'ın Amerikan türüne sahip olduğunu biliyorsanız, tüm diktat diktlerini gereksiz yere yinelemeyin:

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

Tüm bu durumlarda, sözlüklerin girişleri gerçekte hangi sırada sakladığı önemli değildir. Siparişle ilgili gerçekten endişeleriniz varsa, bir OrderedDict:

http://docs.python.org/dev/library/collections.html#collections.OrderedDict


20

Açıklamanızı fark ettiğim gibi, ayrıştırıcınızın size değerlerinin de şu şekilde sözlük olduğu bir sözlük vereceğini biliyorsunuz:

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

Bu yüzden ana sözlüğünüzü tekrarlamalısınız. sampleDict.values()Listedeki ilk sözlük tuşlarının tümünü yazdırmak veya bunlara erişmek istiyorsanız, şunun gibi bir şey kullanabilirsiniz:

for key, value in sampleDict.items():
    print value.keys()[0]

Yalnızca içindeki ilk öğenin ilk anahtarına erişmek istiyorsanız sampleDict.values(), bu yararlı olabilir:

print sampleDict.values()[0].keys()[0]

Soruda verdiğiniz örneği kullanırsanız, demek istediğim:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

İlk kodun çıktısı:

American
Indian

Ve ikinci kodun çıktısı:

American

10

Bonus olarak, sorununuz için farklı bir çözüm sunmak isterim. Görünüşe göre iç içe geçmiş sözlüklerle uğraşıyorsunuz, bu genellikle sıkıcıdır, özellikle de bir iç anahtarın varlığını kontrol etmeniz gerektiğinde.

Pypi'de bununla ilgili bazı ilginç kütüphaneler var, işte hızlı bir arama size .

Sizin özel durumunuzda, dict_digger uygun görünüyor.

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None

8

Sözlükteki dict['Apple'].keys()[0]ilk anahtarı almak için kullanabilirsiniz Apple, ancak olacağının garantisi yoktur American. Sözlükteki tuşların sırası, sözlüğün içeriğine ve tuşların eklenme sırasına göre değişebilir.


Eğer kullanmadığınız sürece OrderedDictde collectionskütüphaneye
Escachator

7

Bunun 8 yaşında olduğunu biliyorum ama aslında kimse soruyu okuyup cevaplamamış görünüyor.

İç diktlerin bir listesini almak için bir diktede .values ​​() 'i çağırabilir ve böylece onlara indeksle erişebilirsiniz.

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']

2
ilginç, bunu denedim ve aldım 'dict_values' object does not support indexing . Bir listeyi kurtarmak için dict_values'i kaydırmanız gerektiğinden bu cevabın güncellenmesi gerektiğini tahmin edin
Yuca

1
@Yucca - Haklıydın, kodumu test etmedim. Cevap güncellendi
Jamie Marshall



1

Bu soruya verilen pek çok yanıta rağmen, çok az kişi sözlüklerin sırasız eşlemeler olduğunu ve bu nedenle (Python 3.7 ile ekleme sırasının kutsanmasına kadar) bir sözlükte kelimenin tam anlamıyla yapılmış "ilk" giriş fikrini belirtti. saçma. Ve hatta bir OrderedDictbile yalnızca mydict[mydict.keys()[0]](Python 3'te keys()abone olunamayan bir yineleyici olduğundan, yalnızca Python 2) gibi çirkinlikler kullanılarak sayısal indeksle erişilebilir .

3.7'den itibaren ve pratikte 3,6'da da - yeni davranış o zaman tanıtıldı, ancak 3.7'ye kadar dil spesifikasyonunun bir parçası olarak dahil edilmedi - bir diktenin anahtarları, değerleri veya öğeleri üzerinde yineleme (ve inanıyorum ki, set ayrıca) ilk olarak en son eklenen nesneleri verir. Bunlara sayısal ekleme indeksi ile erişmenin hala basit bir yolu yoktur.

Öğeleri seçme ve "biçimlendirme" sorusuyla ilgili olarak, sözlükte geri almak istediğiniz anahtarı biliyorsanız, normalde anahtarı almak için bir alt simge olarak kullanırsınız ( my_var = mydict['Apple']).

Öğeleri gerçekten giriş numarasına göre indeksleyebilmek istiyorsanız (belirli bir girişin numarasının eklemeler yapıldıkça değişeceği gerçeğini göz ardı ederek), o zaman uygun yapı muhtemelen iki öğeli demetlerden oluşan bir liste olacaktır. Onun yerine

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

şunları kullanabilirsiniz:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

Bu rejim altında, ilk giriş mylist[0]klasik liste sonu formundadır ve değeri şeklindedir ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). Tüm listeyi aşağıdaki gibi yineleyebilirsiniz:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

ama "Elma" anahtarını aradığınızı biliyorsanız, neden bunun yerine bir dikt kullanmayasınız?

Anahtarların listesini önbelleğe alarak ek bir yönlendirme düzeyi sunabilirsiniz, ancak iki veri yapısını eşzamanlı tutmanın karmaşıklığı kaçınılmaz olarak kodunuzun karmaşıklığını artıracaktır.


0

Aşağıdaki küçük işlevle, ağaç şeklindeki bir sözlüğe girmek oldukça kolay hale gelir:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

Şimdi, dig(mydict, "Apple.Mexican") alt ağacı 10verirken geri döner . Kilit sözlük, içerdiği değilse getirilerdig(mydict, "Grape"){'Arabian':'25','Indian':'20'}digNone .

Ayırıcı karakterini '.' Öğesinden kolayca değiştirebileceğinizi (hatta parametreleştirebileceğinizi) unutmayın. '/', '|' vb.

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.