Python'daki sözlükteki rastgele bir öğeye erişme


507

A mydictboş değilse, isteğe bağlı bir öğeye şu şekilde erişirim:

mydict[mydict.keys()[0]]

Bunu yapmanın daha iyi bir yolu var mı?


3
Ne demişti .. bu sadece dikte sadece bir unsur varsa ya da hangisini geri aldığın önemli değilse geçerli bir soru.
Kraliyet

5
Evet, sadece dikte içindeki herhangi bir öğeye erişmem gerekiyor, bu yüzden ilk öğeye erişmek istiyorum.
Stan

2
@Stan: ama Greg'in dediği gibi, dikte kesin bir "ilk" öğe yoktur. belki de sorunuzu değiştirmelisiniz, sadece net olmak için
tdihp

10
Bunun geçerli bir soru olduğunu düşünüyorum. İsteğe bağlı bir öğeye erişmeniz gerekiyorsa ve bu diktenin boş olmadığından eminseniz, öğe sayısı bilinmeyebileceğinden, "ilk" i istemek iyi bir fikir olabilir.
kap

7
@MichaelScheper Listeye döküm vardır: list(mydict.keys())[0].
Daniel Moskovich

Yanıtlar:


600

Python 3'te, tahribatsız ve tekrarlı olarak:

next(iter(mydict.values()))

Python 2'de, tahribatsız ve tekrarlı olarak:

mydict.itervalues().next()

Hem Python 2 hem de 3'te çalışmasını istiyorsanız, sixpaketi kullanabilirsiniz :

six.next(six.itervalues(mydict))

Ancak bu noktada oldukça şifreli ve kodunuzu tercih ederim.

Herhangi bir öğeyi kaldırmak istiyorsanız şunları yapın:

key, value = mydict.popitem()

"İlk" in burada uygun bir terim olmayabileceğini unutmayın, çünkü dictPython <3.6'da sıralı bir tip değildir. Python 3.6+ dictssipariş edilir.


35
Bunu mu demek istediniz dict.iterkeys().next()?
John Machin

12
@John Machin: Soru, ilk anahtarla ilişkili değere erişiyor gibi görünüyor, bu yüzden cevapta yaptığım da bu.
doublep

5
Bu daha iyi görünüyor: dict.values().__iter__().__next__():)
Vitaly Zdanevich

17
dict.keys () öğesinin doğrudan yinelenememesi can sıkıcı bir durumdur.
semiomant

3
Tahribatsız bir popitem için (sığ) bir kopya oluşturabilirsiniz:key, value = dict(d).popitem()
Pelle

140

Sadece bir öğeye erişmeniz gerekiyorsa (dikte siparişi garanti etmediğinden, şans eseri ilk olmak), bunu sadece Python 2'de yapabilirsiniz :

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

Lütfen unutmayın (en iyi bildiğim kadarıyla) Python, bu yöntemlerden herhangi birine yapılan 2 ardışık aramanın aynı siparişle liste döndüreceğini garanti etmez. Bu Python3 ile desteklenmez.

içinde Python 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
Bu sadece Python 2.x çalışır, 3.x için kullanmanız gerekirlist(my_dict.keys())[0]
alldayremix

6
Peki, bu hangi karmaşıklık sınıfı? Elbette list(my_dict.keys())[0]tembel değil mi?
Evgeni Sergeev

1
Açıklığa kavuşturmak için, @alldayremix'in bu yorumla ne anlama geldiği python 3.x my_dict.function () sonuçlarının endekslemeyi desteklemediğini, bu yüzden önce bir listeye dönüştürmemiz ve ardından dizini kullanabilmemiz gerekir [0]
Noki

57

Python3'te, Yol:

dict.keys() 

türünde bir değer döndür: dict_keys (), bu şekilde dict anahtarlarının 1. üyesi bu şekilde olduğunda bir hata alırız:

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

Son olarak, dict.keys () öğesini @ 1 numaralı listeye dönüştürdüm ve liste ekleme yöntemiyle 1. üye aldım:

list(dict.keys())[0]

Bu en kolay çözümdür ve hem python2 hem de python3'te çalışır.
mattmilten

Param için. Bu cevabın en sezgisel olduğunu söylüyorum
Thomas Valadez

Evet, ama bu OP sorusuna cevap vermiyor, bu da DEĞERLER'e nasıl ulaşılacağı, anahtarlara değil.
Mike Williamson

1
@MikeWilliamson umarım çoğu okuyucu bir anahtar verilen ilgili değerin bir python diksiyonundan nasıl alınacağını bilir.
eric

5
İsteğe bağlı bir anahtar değil, rastgele bir öğe almak için benzer şekilde yapabilirsiniz list(dict.values())[0].
jhin

24

bir anahtar almak

next(iter(mydict))

bir değer elde etmek

next(iter(mydict.values()))

ikisini de almak

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

İlk ikisi Python 2 ve 3'tür. Son ikisi Python 3'te tembeldir, ancak Python 2'de değildir.


16

Diğerlerinin de belirttiği gibi, sözlüklerin garanti sırası olmadığından (ilk tablo olarak uygulandıklarından) "ilk öğe" yoktur. Örneğin, en küçük anahtara karşılık gelen değer thedict[min(thedict)]bunu yapar. Anahtarların yerleştirilme sırasına dikkat ederseniz, yani "ilk" ile "en erken eklenen" anlamına gelirseniz, Python 3.1'de koleksiyonları kullanabilirsiniz . Python'un eski sürümleri için, burada bulabileceğiniz sıralı dict backport'u (2.4 ve üstü) indirin, yükleyin ve kullanın .

Python 3.7 Şimdi dikteler ekleme talimatı verildi.


11

Buna ne dersin. Burada henüz bahsedilmedi.

py 2 ve 3

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

5
dict.values()bir görünüm döndürür, dolayısıyla O (1) olmalıdır. list(a)yeni bir liste döndürür, O (n) olur.
Boycy

Ayrıca a = {"a": {"1"}}
qasimzee

11

Karar sırasını çevreleyen sorunları görmezden gelmek, daha iyi olabilir:

next(dict.itervalues())

Bu şekilde, öğe aramasından ve kullanmadığımız anahtarların bir listesini oluşturmaktan kaçınırız.

Python3

next(iter(dict.values()))

2
değerleri () tüm değerlerin bir kopyasını oluşturur (tuşlar için () tuşları gibi), bu da birçok işlemi O (n ^ 2) yapar.
Glenn Maynard

OP sürümü de öyle mi? Bunu yineleyici kullanmak için değiştireceğim.
Matt Joiner

4
Bu sadece Python 2'dir. Python 3 için, next(iter(dict.values()))listeyi oluşturmadan aynı sonucu almamız gerekir .
kap


2

Her zaman şunları yapabilirsiniz:

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

Bu, sıralamanın sizin için bir anlamı varsa, üzerinde işlem yapabileceğiniz tutarlı bir şekilde sıralanmış ( yerleşik .hash () ile ilgili ) bir anahtar kümesi verecektir. Bu, örneğin, sözlüğü genişletseniz bile sayısal türlerin tutarlı bir şekilde sıralandığı anlamına gelir.

MİSAL

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

Yazdırıldığında sözlüğün sıralandığını unutmayın. Ama anahtar set aslında bir hashmap!


2

Hem Python 2 hem de 3 için:

import six

six.next(six.itervalues(d))

Bu soruya bir cevap sağlamaz. Bir yazardan eleştiri veya açıklama istemek için gönderilerinin altına bir yorum bırakın.
Martin Tournoij

Bu, soruyu Is there any better way to do this?kısa sürede tam olarak cevaplar .
oblalex

Bu cevap iki kez verilmiştir, bunlardan biri neredeyse 5 yıldır bu sitede bulunmaktadır. Bu başka bir cevaba yapılan bir yorumdur (olduğu gibi: " Python 2 & 3 ile birlikte çalışmasını sağlamak için cevabı nasıl geliştireceğimiz " ve bunun gibi "yeni" bir cevap değil. SO'nun inceleme sistemi bu durumda otomatik olarak biraz yararsız bir not yerleştirdi ...
Martin Tournoij

Hayır, efendim. Bu değişkeni, 17 saat önce, bu yanıtı yazdıktan 1 saat sonra, 5 yaşındaki yanıtınıza eklediniz. Bu sayfada 'altı' kelimesi için 'bul' kullanmaya çalışın ve sadece bu 2 cevapta sadece 6 eşleşme bulacaksınız. Her neyse, bu cevap sizi gerçekten rahatsız ediyor mu? Bence bu gelecekte başka insanlara da yardımcı olabilir ve sorun değil. Peki, anlaşma nedir?
oblalex

Bunun nedeni, IMHO'nun bu cevabın en başta o yayının bir düzenlemesi olması gerektiğidir. Düzenleme olmadan, insanların cevabınızı görmek için birkaç sayfayı aşağı kaydırmaları gerekir; bunun sizinkiyle hemen hemen aynı olan son derece güncel bir yanıtı düzenlemekten daha yararlı olduğunu düşünüyor musunuz?
Martin Tournoij


-1

Harici kütüphane yok, hem Python 2.7 hem de 3.x üzerinde çalışıyor:

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

Aribtrary anahtarı için .values ​​()

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

-2

Alt sınıflandırma dictetkili olmasa da bir yöntemdir. Burada bir tamsayı verirseniz döndürülür d[list(d)[n]], aksi takdirde sözlüğe beklendiği gibi erişin:

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'
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.