Sözlükteki değere göre anahtarı alın


632

Bir yaş içinde arayacak Dictionaryve eşleşen adı gösterecek bir işlev yaptım :

dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
for age in dictionary.values():
    if age == search_age:
        name = dictionary[age]
        print name

Yaşın nasıl karşılaştırılacağını ve bulunacağını biliyorum, sadece kişinin adını nasıl göstereceğimi bilmiyorum. Ayrıca, KeyError5. satır nedeniyle alıyorum. Doğru olmadığını biliyorum ama geriye doğru arama yapmak nasıl anlayamıyorum.



Sözlükteki tanımına göre bir kelime bulabilir misiniz? HAYIR.
Jossie Calderon

Yanıtlar:


563

Hiç yok. dictbu şekilde kullanılması amaçlanmamıştır.

dictionary = {'george': 16, 'amber': 19}
search_age = input("Provide age")
for name, age in dictionary.items():  # for name, age in dictionary.iteritems():  (for Python 2.x)
    if age == search_age:
        print(name)

137
Bunun Python 3.x list.items()yerine list.iteritems()kullanılmalıdır
Yuriy Petrovskiy

63
Kabul etmiyorum ... agf'ın aşağıdaki cevabı daha yapıcı. Mükemmel derecede makul bir kullanım durumu "istenmeyen" değildir (liste kavrayışı böyle bir kullanım durumuna uygundur). A dictfarklı zamanlarda birden çok şey için olabilir; anahtarların ve değerlerin elbette açık bir anlamı vardır, ancak " dictbelirli bir değere sahip öğeler" son derece makul bir taleptir. Bir çiftler listesinin kullanılması önerisi, bir öğenin diğerinden ' tanım ' olduğu bağlamını , örneğin parametre listelerinde atacaktır ...
Louis Maddox

1
Bu cevaba katılmıyorum. Stênio Elson tarafından yanıt olarak gösterildiği gibi bir olasılık olması, bu şekilde kullanılması amaçlanmadığı anlamına gelmez. Hiç yardımcı değil.
Tropicalrambler

Bir sözlükte tanımına göre bir kelime bulur musunuz? HAYIR. @Tropicalrambler
Jossie Calderon

Bir kelime sözlüğü için standart bir kullanımın, kelimenin tanımını word = anahtar ve definition = değer ile aramak olduğu bir noktaya sahip olsanız da, günümüzün programlama dilleri gerektiğinde değere göre arama yapmanızı sağlar. Bir key: value pair nesnesi ile çalışıyorsanız (sözlü dil için herhangi bir ad varsa, sözlüğü, tuple deyin). Python'da, karşılık gelen tuşları bulmak için yapının değerleri arasında endeksleme yapabileceğiniz bir gerçektir.
Tropicalrambler

599
mydict = {'george': 16, 'amber': 19}
print mydict.keys()[mydict.values().index(16)]  # Prints george

Veya Python 3.x'te:

mydict = {'george': 16, 'amber': 19}
print(list(mydict.keys())[list(mydict.values()).index(16)])  # Prints george

Temel olarak, sözlükteki değerleri bir listede ayırır, sahip olduğunuz değerin konumunu bulur ve anahtarı bu konuma alır.

Python 3 hakkında keys()ve daha fazlası .values(): Dict'ten değerlerin listesini nasıl alabilirim?


23
Harika görünüyor ama her zaman çalışıyor mu? Yani, işlevler list.keys()ve list.values()işlevler aynı sırayla öğeleri oluşturur mu?
iskorum

17
Evet, tutarlı olmaları garanti edilir. Ayrıca, sözlük değiştirilmediği sürece siparişin yinelemelerde değişmemesi garanti edilir.
Veedrac

9
Bu iyi bir çözüm gibi görünüyor ama dizin sadece bir değer sağ verdi, bu yüzden birden fazla eşit değer ve varsa, birden fazla anahtar doğru döndürmelidir?
James Sapam

12
@ArtOfWarfare docs.python.org/3/library/stdtypes.html#dict-views , "Anahtarlarda, değerlerde ve öğe görünümlerinde sözlükte herhangi bir değişiklik yapılmadan yinelenirse, öğelerin sırası doğrudan karşılık gelir."
Veedrac

5
@sinekonata: Başlık altında hala pahalı bir döngü gerçekleştiriyor; döngü sadece indexyöntemin içinde gizlidir .
user2357112 Monica

252

Hem adı hem de yaşı istiyorsanız .items(), size anahtar (key, value)tuples veren hangisini kullanmalısınız :

for name, age in mydict.items():
    if age == search_age:
        print name

Paketi, fordöngü içinde iki ayrı değişkene açıp yaşla eşleştirebilirsiniz.

Genelde yaşa göre arama yapacaksanız ve iki kişinin aynı yaşta olmaması durumunda sözlüğü tersine çevirmeyi de düşünmelisiniz:

{16: 'george', 19: 'amber'}

böylece bir yaşın adını sadece

mydict[search_age]

Bunu aradım mydictyerine listçünkü listadıdır bir tür dahili ve başka bir şey için bu ismi kullanmamalıdır.

Hatta belirli bir yaştaki tüm kişilerin bir satırda bir listesini alabilirsiniz:

[name for name, age in mydict.items() if age == search_age]

veya her yaşta yalnızca bir kişi varsa:

next((name for name, age in mydict.items() if age == search_age), None)

Nonebu yaşta kimse yoksa size verecektir .

Son olarak, dictuzunsa ve Python 2'deyseniz , listenin bir kopyasını oluşturması gerekmediğinden Cat Plus Plus'ın yanıtı .iteritems()yerine kullanmayı düşünmelisiniz .items().


9
Doğru, ancak doğrusal arama yapacaksanız, yerine dictbir çiftler listesi de ekleyebilirsiniz .
Fred Foo

9
Her zamanki eyleminiz yaşlandıkça yaşlanmadıkça, bu durumda dictmantıklıdır.
agf

2
Öte yandan, her yaşta sadece bir kişi olduğunu varsaymak garip görünüyor, öte yandan, her bir kişinin tek bir yaşta olması tamamen mantıklıdır.
Dannid

@Dannid Evet, ancak sorun kolayca genelleştirilebilir. Örneğin, benzersiz anahtarları ve bunlara karşılık gelen benzersiz değerleri içeren bir arama tablonuz olabilir. Daha sonra şeyleri simetrik olarak value --> keykey --> value
arayabilirsiniz

68

Hangi yöntemlerin en hızlı ve hangi senaryoda olduğunu belirtmenin ilginç olacağını düşündüm:

İşte yaptığım bazı testler (2012 MacBook Pro'da)

>>> def method1(list,search_age):
...     for name,age in list.iteritems():
...             if age == search_age:
...                     return name
... 
>>> def method2(list,search_age):
...     return [name for name,age in list.iteritems() if age == search_age]
... 
>>> def method3(list,search_age):
...     return list.keys()[list.values().index(search_age)]

Elde edilen sonuçlar, profile.run()her bir yöntemin 100000 kat ile:

Yöntem 1:

>>> profile.run("for i in range(0,100000): method1(list,16)")
     200004 function calls in 1.173 seconds

Yöntem 2:

>>> profile.run("for i in range(0,100000): method2(list,16)")
     200004 function calls in 1.222 seconds

Yöntem 3:

>>> profile.run("for i in range(0,100000): method3(list,16)")
     400004 function calls in 2.125 seconds

Bu, küçük bir dikte için yöntem 1'in en hızlı olduğunu gösterir. Bunun nedeni büyük olasılıkla yöntem 2 gibi tüm eşleşmelerin aksine ilk eşleşmeyi döndürmesidir (aşağıdaki nota bakın).


İlginç bir şekilde, aynı testleri 2700 giriş ile sahip olduğum bir dikte üzerinde gerçekleştirerek, oldukça farklı sonuçlar alıyorum (bu sefer 10000 kez çalışıyor):

Yöntem 1:

>>> profile.run("for i in range(0,10000): method1(UIC_CRS,'7088380')")
     20004 function calls in 2.928 seconds

Yöntem 2:

>>> profile.run("for i in range(0,10000): method2(UIC_CRS,'7088380')")
     20004 function calls in 3.872 seconds

Yöntem 3:

>>> profile.run("for i in range(0,10000): method3(UIC_CRS,'7088380')")
     40004 function calls in 1.176 seconds

Yani burada yöntem 3 çok daha hızlı. Sadece diktinizin boyutunun seçtiğiniz yöntemi etkileyeceğini göstermeye gider.

Notlar: Yöntem 2 tüm adların bir listesini döndürürken , yöntem 1 ve 3 yalnızca ilk eşleşmeyi döndürür. Bellek kullanımını düşünmedim. Yöntem 3, 2 ekstra liste (anahtarlar () ve değerler ()) oluşturup bellekte saklayıp saklamadığından emin değilim.


6
Sadece bir güncelleme: Görünüşe göre dict.values ​​() ve dict.keys () her ikisi de orijinal dict'teki nesnelere referans veren listeler döndürür, bu nedenle yöntem 3 aynı zamanda en az belleği kullanan yöntemdir (yalnızca iki ince liste nesnesi oluşturur) diğerleri yineleyici öğeler oluşturur
Patrick

Ben sadece kendimi kıyaslamak istedim, aşağı kaydırdım, bam orada. Teşekkürler! Teknik olarak zaten belirttiğiniz gibi yöntem 2, 1 ve 3 ile aynı şeyi yapmaz, çünkü tüm eşleşmeleri döndürür. örneğin bir sonraki dönüş ([..]) için sonuçları görmek güzel olurdu.
BluBb_mADe

Yapılması gereken bir diğer önemli not ise Python versiyonudur. Bazı sürümlerin diğerlerinden daha verimli yöntem uygulamaları olduğunu biliyorum.
ArtOfWarfare

@Patrick: tüm yöntemler değerlere ve anahtarlara doğrudan referanslar kullanır, herhangi bir bellek avantajı yoktur. Python 3 .keys()ve` hariç .values(), hafif olan sözlük görünümlerini döndürür.
Martijn Pieters

53

bir satır sürümü: (i eski bir sözlük, p ters bir sözlük)

Açıklama: i.keys()ve i.values()sırasıyla anahtarların ve değerlerin bulunduğu iki liste döndürür. Zip işlevi, sözlük oluşturmak için listeleri birbirine bağlama özelliğine sahiptir.

p = dict(zip(i.values(),i.keys()))

Uyarı: Bu yalnızca değerler yıkanabilir ve benzersiz olduğunda çalışır.


Evet, bu işe
yarar

17
... ve yinelenen değerler olmadığında.
ely

3
Güzel. Yukarıdaki yorum, elbette sadece yinelenen değerler olmadığında çalışır, ancak daha sonra, bu iş parçacığını başlatan soru, bire bir fonksiyonumuz olduğu varsayımını yapar, bu nedenle bu varsayım, en zarif çok yanıt.
John Strong

1
yıkanabilir değerler üzerinde genişleme: değerleriniz listeler / kümeler ise, bunun çalışması için bunları tuple dönüştürür (yine de benzersiz olmaları gerekir).
muon

28
a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

ya da daha iyisi

{k:v for k, v in a.items() if v == 1}

5
A'nın aynı değerini tutan başka bir anahtar varsa ne olur? Pitonik bir yol olabilir. Ama iyi bir fikir değil.
7H3 IN5ID3R

iyi bir noktaya, ben nonunique değerlerle çalışır çözeltisi ilave
Jelen

26
key = next((k for k in my_dict if my_dict[k] == val), None)

Aynı satırda 'başka' da olabilir mi?
Değerimin dik

lKey = [k for k, v in lDictionary.iteritems() if v == lValue][0] or 'else-key'
faham

14

Bir sözlüğü tersine çevirmek için bu tek satırı deneyin:

reversed_dictionary = dict(map(reversed, dictionary.items()))

1
Bu benim şifreleme ve şifre çözme programım için harika çalıştı, teşekkürler!
Christian R


@pfabri ???????
johnaphun

13

Bu cevabı çok etkili buldum ama benim için okuması çok kolay değil.

Daha açık hale getirmek için, bir sözlüğün anahtarını ve değerini tersine çevirebilirsiniz. Bu, burada görüldüğü gibi, anahtar değerleri ve değerler anahtarlarını yapmaktır .

mydict = {'george':16,'amber':19}
res = dict((v,k) for k,v in mydict.iteritems())
print(res[16]) # Prints george

veya

mydict = {'george':16,'amber':19}
dict((v,k) for k,v in mydict.iteritems())[16]

ki bu aslında diğer cevap ile aynıdır .


12

Anahtarı değere göre bulmak istiyorsanız, bir arama sözlüğü oluşturmak için bir sözlük kavrama kullanabilir ve daha sonra bunu değerden anahtarı bulmak için kullanabilirsiniz.

lookup = {value: key for key, value in self.data}
lookup[value]

11

Sen kullanarak anahtarı elde edebilirsiniz dict.keys(), dict.values()ve list.index()aşağıda kod örnekleri görmek, yöntemleri:

names_dict = {'george':16,'amber':19}
search_age = int(raw_input("Provide age"))
key = names_dict.keys()[names_dict.values().index(search_age)]

2
Eğer tanımlı kullanmayın search_ageBelki değiştirmeniz gerekir ... sonraki satırda Var valueolan search_age?
Andersson

2
Bu hatayı alıyorum: 'dict_values' nesnesinin 'index' özelliği yok
Blue_Elephant

@Blue_Elephant, hata ve python sürümünüz olan kod snippet'ini sağlayabilir misiniz (ayrıca yazdırma type(dict_values)yararlı olur)?
Andriy Ivaneyko

9

İşte bu sorunu ele almam. :) Python öğrenmeye yeni başladım, bu yüzden buna şöyle diyorum:

"Yeni başlayanlar için anlaşılır" çözüm.

#Code without comments.

list1 = {'george':16,'amber':19, 'Garry':19}
search_age = raw_input("Provide age: ")
print
search_age = int(search_age)

listByAge = {}

for name, age in list1.items():
    if age == search_age:
        age = str(age)
        results = name + " " +age
        print results

        age2 = int(age)
        listByAge[name] = listByAge.get(name,0)+age2

print
print listByAge

.

#Code with comments.
#I've added another name with the same age to the list.
list1 = {'george':16,'amber':19, 'Garry':19}
#Original code.
search_age = raw_input("Provide age: ")
print
#Because raw_input gives a string, we need to convert it to int,
#so we can search the dictionary list with it.
search_age = int(search_age)

#Here we define another empty dictionary, to store the results in a more 
#permanent way.
listByAge = {}

#We use double variable iteration, so we get both the name and age 
#on each run of the loop.
for name, age in list1.items():
    #Here we check if the User Defined age = the age parameter 
    #for this run of the loop.
    if age == search_age:
        #Here we convert Age back to string, because we will concatenate it 
        #with the person's name. 
        age = str(age)
        #Here we concatenate.
        results = name + " " +age
        #If you want just the names and ages displayed you can delete
        #the code after "print results". If you want them stored, don't...
        print results

        #Here we create a second variable that uses the value of
        #the age for the current person in the list.
        #For example if "Anna" is "10", age2 = 10,
        #integer value which we can use in addition.
        age2 = int(age)
        #Here we use the method that checks or creates values in dictionaries.
        #We create a new entry for each name that matches the User Defined Age
        #with default value of 0, and then we add the value from age2.
        listByAge[name] = listByAge.get(name,0)+age2

#Here we print the new dictionary with the users with User Defined Age.
print
print listByAge

.

#Results
Running: *\test.py (Thu Jun 06 05:10:02 2013)

Provide age: 19

amber 19
Garry 19

{'amber': 19, 'Garry': 19}

Execution Successful!

9
get_key = lambda v, d: next(k for k in d if d[k] is v)

Güzel bir astar. Ancak, isyalnızca tekil değerlerin eşitlik testi için kullanılmalıdır (None , True, Falsevb.) CPython (ve dolayısıyla dize hazır kalıncaya gerçeği a = 'foobar'; a is 'foobar'olan True) bir uygulama ayrıntıdır ve üzerinde itibar edilmemelidir.
piit79

1
Ve bir yorum daha: değer sözlükte yoksa get_keyatar - StopIterationdeğer bulunmazsa next(..., None)döndürülecek daha iyi olur None.
piit79

Sözlük tek öğeler içermiyor, ancak ayarlıyorsa küçük bir değişiklik işe yarayacaktır:get_first_key = lambda v, d: next((k for k in d if (v in d[k] is not None)), None)
supernova

7

Pandaları kullanmayı düşünün. William McKinney'in "Veri Analizi için Python" da belirtildiği gibi

Bir Seri hakkında düşünmenin bir başka yolu, sabit uzunluklu, sıralı bir dikte, çünkü indeks değerlerinin veri değerleriyle eşleştirilmesidir. Bir diksiyon kullanabileceğiniz birçok bağlamda kullanılabilir.

import pandas as pd
list = {'george':16,'amber':19}
lookup_list = pd.Series(list)

Dizinizi sorgulamak için aşağıdakileri yapın:

lookup_list[lookup_list.values == 19]

Hangi verim:

Out[1]: 
amber    19
dtype: int64

Çıktı ile yanıtı bir listeye dönüştürmek için başka bir şey yapmanız gerekirse yararlı olabilir:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)

Pandaların yaratıcısı. Yine de Wes olarak bilinir.
Axel

6

Burada, WORD_key, sözlükte bulmak için sözlüğü ve değeri alır. Daha sonra sözlükteki anahtarların üzerinden geçer ve değerle bir karşılaştırma yaparız ve o anahtarı döndürürüz.

def recover_key(dicty,value):
    for a_key in dicty.keys():
        if (dicty[a_key] == value):
            return a_key

5

Alabileceğimiz Keyarasında dictölçütü:

def getKey(dct,value):
     return [key for key in dct if (dct[key] == value)]

4
for name in mydict:
    if mydict[name] == search_age:
        print(name) 
        #or do something else with it. 
        #if in a function append to a temporary list, 
        #then after the loop return the list

1
For döngüsü ve ekleme kullanmak liste kavrayışından çok daha yavaştır ve daha uzundur.
alexpinho98

3

yanıtlandı, ancak süslü bir 'harita / azaltma' kullanımı ile yapılabilir, örneğin:

def find_key(value, dictionary):
    return reduce(lambda x, y: x if x is not None else y,
                  map(lambda x: x[0] if x[1] == value else None, 
                      dictionary.iteritems()))

3

Cat Plus Plus, bir sözlüğün bu şekilde kullanılması amaçlanmadığını belirtti. İşte nedeni:

Bir sözlüğün tanımı, matematikteki bir eşlemenin tanımına benzer. Bu durumda, bir dikte K (anahtarlar dizisi) 'nin V (değerler) ile eşleştirilmesidir - fakat tersi değildir. Bir itirazı iptal ederseniz, tam olarak bir değer döndürülmesini beklersiniz. Ancak, farklı anahtarların aynı değere eşlenmesi mükemmel bir yasaldır, örneğin:

d = { k1 : v1, k2 : v2, k3 : v1}

Bir anahtara karşılık gelen değerle baktığınızda, aslında sözlüğü tersine çevirirsiniz. Ancak bir haritalama mutlaka ters çevrilemez! Bu örnekte, v1'e karşılık gelen anahtarı istemek k1 veya k3 verebilir. İkisini de geri getirmeli misin? Sadece birincisi mi buldun? Bu nedenle indexof (), sözlükler için tanımlanmamıştır.

Verilerinizi biliyorsanız, bunu yapabilirsiniz. Ancak bir API, rastgele bir sözlüğün tersine çevrilebilir olduğunu ve dolayısıyla böyle bir işlemin bulunmadığını varsayamaz.


3

İşte benim almam. Bu, ihtiyacınız olduğunda birden fazla sonuç görüntülemek için iyidir. Listeyi de ekledim

myList = {'george':16,'amber':19, 'rachel':19, 
           'david':15 }                         #Setting the dictionary
result=[]                                       #Making ready of the result list
search_age = int(input('Enter age '))

for keywords in myList.keys():
    if myList[keywords] ==search_age:
    result.append(keywords)                    #This part, we are making list of results

for res in result:                             #We are now printing the results
    print(res)

Ve bu kadar...


3
d= {'george':16,'amber':19}

dict((v,k) for k,v in d.items()).get(16)

Çıktı aşağıdaki gibidir:

-> prints george

[k için k, d =
öğelerde

3

Değeri 'arayarak' listede bir anahtar bulmanın kolay bir yolu yoktur. Ancak, anahtarları yineleyen değeri biliyorsanız, sözlükteki değerleri öğeye göre arayabilirsiniz. D'nin bir sözlük nesnesi olduğu D [elemanı], aramaya çalıştığınız tuşa eşitse, bazı kodları yürütebilirsiniz.

D = {'Ali': 20, 'Marina': 12, 'George':16}
age = int(input('enter age:\t'))  
for element in D.keys():
    if D[element] == age:
        print(element)

3

Bir sözlük kullanmanız ve sözlüğün tersini kullanmanız gerekir. Başka bir veri yapısına ihtiyacınız olduğu anlamına gelir. Python 3'te iseniz, enummodülü kullanın, ancak python 2.7 kullanıyorsanızenum34 python 2 için geri taşınan .

Misal:

from enum import Enum

class Color(Enum): 
    red = 1 
    green = 2 
    blue = 3

>>> print(Color.red) 
Color.red

>>> print(repr(Color.red)) 
<color.red: 1=""> 

>>> type(Color.red) 
<enum 'color'=""> 
>>> isinstance(Color.green, Color) 
True 

>>> member = Color.red 
>>> member.name 
'red' 
>>> member.value 
1 

2
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name

1
Neden anahtar sözlükten kaldırılıyor? bu soruya cevap vermiyor
Jean-François Fabre

2

Sadece cevabım lambdave filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )

1

zaten yanıtlandı, ancak birkaç kişi sözlüğü tersine çevirmekten bahsettiğinden, bunu bir satırda (1: 1 haritalama varsayarak) ve bazı çeşitli mükemmel verileri nasıl yaptığınız aşağıda açıklanmıştır:

python 2.6:

reversedict = dict([(value, key) for key, value in mydict.iteritems()])

2.7+:

reversedict = {value:key for key, value in mydict.iteritems()}

1: 1 olmadığını düşünüyorsanız, yine de birkaç satırla makul bir ters harita oluşturabilirsiniz:

reversedict = defaultdict(list)
[reversedict[value].append(key) for key, value in mydict.iteritems()]

bu ne kadar yavaş: basit bir aramadan daha yavaş, ancak düşündüğünüz kadar yavaş değil - 'düz' 100000 giriş sözlüğünde, 'hızlı' arama (yani anahtarlarda erken olması gereken bir değer aramak) tüm sözlüğü tersine çevirmekten yaklaşık 10 kat daha hızlı ve 4-5 kat daha hızlı bir 'yavaş' arama (sonuna doğru). Bu yüzden en fazla 10 arama yaptıktan sonra kendisi için ödeme yapılır.

ikinci sürüm (öğe başına liste içeren), basit sürüm olduğu sürece yaklaşık 2,5 kat alır.

largedict = dict((x,x) for x in range(100000))

# Should be slow, has to search 90000 entries before it finds it
In [26]: %timeit largedict.keys()[largedict.values().index(90000)]
100 loops, best of 3: 4.81 ms per loop

# Should be fast, has to only search 9 entries to find it. 
In [27]: %timeit largedict.keys()[largedict.values().index(9)]
100 loops, best of 3: 2.94 ms per loop

# How about using iterkeys() instead of keys()?
# These are faster, because you don't have to create the entire keys array.
# You DO have to create the entire values array - more on that later.

In [31]: %timeit islice(largedict.iterkeys(), largedict.values().index(90000))
100 loops, best of 3: 3.38 ms per loop

In [32]: %timeit islice(largedict.iterkeys(), largedict.values().index(9))
1000 loops, best of 3: 1.48 ms per loop

In [24]: %timeit reversedict = dict([(value, key) for key, value in largedict.iteritems()])
10 loops, best of 3: 22.9 ms per loop

In [23]: %%timeit
....: reversedict = defaultdict(list)
....: [reversedict[value].append(key) for key, value in largedict.iteritems()]
....:
10 loops, best of 3: 53.6 ms per loop

Ayrıca ifilter ile bazı ilginç sonuçlar elde etti. Teorik olarak, ifilter daha hızlı olmalıdır, çünkü itervalues ​​() yöntemini kullanabiliriz ve muhtemelen tüm değerler listesini oluşturmak / bu listeden geçmek zorunda değiliz. Uygulamada, sonuçlar ... tuhaftı ...

In [72]: %%timeit
....: myf = ifilter(lambda x: x[1] == 90000, largedict.iteritems())
....: myf.next()[0]
....:
100 loops, best of 3: 15.1 ms per loop

In [73]: %%timeit
....: myf = ifilter(lambda x: x[1] == 9, largedict.iteritems())
....: myf.next()[0]
....:
100000 loops, best of 3: 2.36 us per loop

Bu nedenle, küçük ofsetler için önceki sürümlerden çok daha hızlıydı (önceki durumlar için minimum 1.48 * m * S'ye kıyasla 2.36 * u * S). Bununla birlikte, listenin sonuna yakın büyük ofsetler için, dramatik şekilde daha yavaştı (aynı 1,48 mS'ye karşı 15,1 ms). Düşük uçtaki küçük tasarruflar, yüksek uçtaki maliyete değmez, imho.


Ben çok bu (reversedict = defaultdict (liste) reversedict [değer] .append (anahtar) için anahtar, largedict.iteritems ()] değeri) çalışmak istiyorum, ama Python 2.7.3 kullanarak, kelime üzerinde sözdizimi hatası alıyorum 'for'
slashdottir

aslında yazdığınız bu mu? [eğer içinde bir eksik var. Aksi takdirde, iki satırda olduğundan emin olun, yoksa ;aralarında bir tane koyun .
Corley Brigman

1

Bazen int () gerekebilir:

titleDic = {'Фильмы':1, 'Музыка':2}

def categoryTitleForNumber(self, num):
    search_title = ''
    for title, titleNum in self.titleDic.items():
        if int(titleNum) == int(num):
            search_title = title
    return search_title

1

İşte Python 2 ve Python 3'te çalışan bir çözüm:

dict((v, k) for k, v in list.items())[search_age]

[search_age]Ters sözlüğü oluşturana kadar olan bölüm (değerlerin anahtar olduğu ve tam tersi). Bu ters çevrilmiş sözlüğü şu şekilde önbelleğe alacak bir yardımcı yöntem oluşturabilirsiniz:

def find_name(age, _rev_lookup=dict((v, k) for k, v in ages_by_name.items())):
    return _rev_lookup[age]

hatta daha genel olarak listelerinizden biri veya daha fazlası için bir yaşa göre arama yöntemi oluşturacak bir fabrika

def create_name_finder(ages_by_name):
    names_by_age = dict((v, k) for k, v in ages_by_name.items())
    def find_name(age):
      return names_by_age[age]

böylece şunları yapabilirsiniz:

find_teen_by_age = create_name_finder({'george':16,'amber':19})
...
find_teen_by_age(search_age)

Ben adını o Not listiçin ages_by_nameeski önceden tanımlanmış bir türüdür beri.


1

İstediğiniz şeyi yapmak için sözlüğe şu şekilde erişirsiniz:

list = {'george': 16, 'amber': 19}
search_age = raw_input("Provide age")
for age in list:
    if list[age] == search_age:
        print age

Tabii ki, isimleriniz o kadar kapalı ki bir yaş basıyor gibi görünüyor, ancak adı yazdırıyor. Ada göre eriştiğiniz için, şunu yazarsanız daha anlaşılır hale gelir:

list = {'george': 16, 'amber': 19}
search_age = raw_input("Provide age")
for name in list:
    if list[name] == search_age:
        print name

Daha iyisi:

people = {'george': {'age': 16}, 'amber': {'age': 19}}
search_age = raw_input("Provide age")
for name in people:
    if people[name]['age'] == search_age:
        print name

1
dictionary = {'george' : 16, 'amber' : 19}
search_age = raw_input("Provide age")
key = [filter( lambda x: dictionary[x] == k  , dictionary ),[None]][0] 
# key = None from [None] which is a safeguard for not found.

Birden fazla tekrarlama için şunları kullanın:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]

*** NameError: global name 'dictionary' is not defined
Bishwas Mishra

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
Bishwas Mishra
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.