Dapatkan kunci dengan nilai dalam kamus

632

Saya membuat fungsi yang akan mencari usia dalam Dictionarydan menunjukkan nama yang cocok:

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

Saya tahu bagaimana membandingkan dan menemukan usia saya hanya tidak tahu bagaimana menunjukkan nama orang tersebut. Selain itu, saya mendapatkan KeyErrorkarena baris 5. Saya tahu itu tidak benar tetapi saya tidak tahu cara membuatnya mundur.

user998316
sumber
Apakah Anda akan menemukan kata berdasarkan definisi dalam kamus? NGGAK.
Jossie Calderon

Jawaban:

563

Tidak ada. dicttidak dimaksudkan untuk digunakan dengan cara ini.

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)
Cat Plus Plus
sumber
137
Dalam Python 3.x list.items()bukannya list.iteritems()harus digunakan
Yuriy Petrovskiy
63
Saya tidak setuju ... jawaban AGF di bawah ini lebih konstruktif. Kasus penggunaan yang sangat masuk akal bukanlah "tidak disengaja" (toh pemahaman daftar cocok dengan kasus penggunaan seperti itu). A dictdapat untuk banyak hal pada waktu yang berbeda; kunci dan nilai memiliki makna yang jelas, tentu saja, tetapi " dictitem dengan nilai yang diberikan" adalah permintaan yang sangat masuk akal. Rekomendasi untuk menggunakan daftar pasangan akan membuang konteks bahwa satu item adalah ' definisi ' dari yang lain, misalnya dalam daftar parameter ...
Louis Maddox
1
Saya tidak setuju dengan jawaban ini. Fakta bahwa itu adalah suatu kemungkinan, seperti ditunjukkan dalam jawaban oleh Stênio Elson, tidak menyiratkan bahwa itu tidak dimaksudkan untuk digunakan seperti itu. Tidak membantu sama sekali.
Tropicalrambler
Apakah Anda akan menemukan kata dalam kamus berdasarkan definisinya? NGGAK. @Tropicalrambler
Jossie Calderon
Meskipun Anda memiliki poin bahwa penggunaan standar untuk kamus kata adalah untuk mencari definisi kata dengan kata = kunci dan definisi = nilai, bahasa pemrograman saat ini memungkinkan Anda untuk mencari berdasarkan nilai jika perlu. Jika Anda bekerja dengan kunci: objek pasangan nilai (sebut saja kamus, tupel, nama apa pun untuk bahasa apa pun). Dalam python, ini adalah fakta bahwa Anda masih dapat mengindeks melalui nilai-nilai struktur untuk mengetahui kunci yang sesuai.
Tropicalrambler
599
mydict = {'george': 16, 'amber': 19}
print mydict.keys()[mydict.values().index(16)]  # Prints george

Atau dengan Python 3.x:

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

Pada dasarnya, ini memisahkan nilai kamus dalam daftar, menemukan posisi nilai yang Anda miliki, dan mendapatkan kunci pada posisi itu.

Lebih lanjut tentang keys()dan .values()dalam Python 3: Bagaimana saya bisa mendapatkan daftar nilai dari dict?

Stênio Elson
sumber
23
Terlihat hebat tetapi apakah itu selalu berhasil? Maksud saya, apakah list.keys()dan list.values()fungsi menghasilkan item dalam urutan yang sama?
iskorum
17
Ya, mereka dijamin konsisten. Selain itu pesanan dijamin tidak akan berubah melalui iterasi selama kamus tidak diubah.
Veedrac
9
Ini terlihat menjadi solusi yang baik tetapi indeks hanya memberikan satu nilai yang benar, jadi jika Anda memiliki beberapa nilai yang sama, maka itu harus mengembalikan beberapa kunci, kan?
James Sapam
12
@ArtOfWarfare docs.python.org/3/library/stdtypes.html#dict-views , "Jika kunci, nilai, dan tampilan item diulangi tanpa modifikasi kamus, urutan item akan secara langsung sesuai."
Veedrac
5
@ sinekonata: Masih melakukan loop mahal di bawah tenda; loop hanya disembunyikan di dalam indexmetode ini.
user2357112 mendukung Monica
252

Jika Anda ingin nama dan usia, Anda harus menggunakan .items()yang memberi Anda (key, value)tupel kunci :

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

Anda dapat membongkar tuple menjadi dua variabel terpisah tepat di forloop, lalu mencocokkan usia.

Anda juga harus mempertimbangkan membalik kamus jika Anda secara umum akan mencari berdasarkan usia, dan tidak ada dua orang yang memiliki usia yang sama:

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

sehingga Anda dapat mencari nama untuk usia hanya dengan melakukan

mydict[search_age]

Saya telah memanggilnya mydictalih-alih listkarena itu listadalah nama tipe bawaan, dan Anda tidak boleh menggunakan nama itu untuk hal lain.

Anda bahkan bisa mendapatkan daftar semua orang dengan usia tertentu dalam satu baris:

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

atau jika hanya ada satu orang dengan setiap usia:

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

yang hanya akan memberi Anda Nonejika tidak ada orang dengan usia itu.

Terakhir, jika dictpanjang dan Anda menggunakan Python 2, Anda harus mempertimbangkan untuk menggunakan .iteritems()daripada yang dilakukan .items()Cat Plus Plus dalam jawabannya, karena itu tidak perlu membuat salinan daftar.

agf
sumber
9
Benar, tetapi jika Anda akan melakukan pencarian linear, Anda mungkin juga mengganti dictdengan daftar pasangan.
Fred Foo
9
Kecuali jika tindakan Anda yang biasa dilakukan adalah mencari nama berdasarkan usia, dalam hal ini dictmasuk akal.
agf
2
Tampaknya aneh untuk mengasumsikan bahwa hanya ada satu orang dengan setiap usia, sementara di sisi lain, sangat logis bagi setiap orang untuk memiliki usia tunggal.
Dannid
@ Jangan Ya, tetapi masalahnya dapat dengan mudah digeneralisasi. Misalnya, Anda bisa melihat tabel dengan kunci unik dan nilai uniknya. Anda kemudian dapat mencari hal-hal secara simetris value --> keyataukey --> value
pfabri
68

Saya pikir akan menarik untuk menunjukkan metode mana yang paling cepat, dan dalam skenario apa:

Inilah beberapa tes yang saya jalankan (pada MacBook Pro 2012)

>>> 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)]

Hasil dari profile.run()pada setiap metode 100000 kali:

Metode 1:

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

Metode 2:

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

Metode 3:

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

Jadi ini menunjukkan bahwa untuk dikte kecil, metode 1 adalah yang tercepat. Ini kemungkinan besar karena mengembalikan kecocokan pertama, sebagai lawan dari semua kecocokan seperti metode 2 (lihat catatan di bawah).


Menariknya, melakukan tes yang sama pada dict yang saya miliki dengan 2.700 entri, saya mendapatkan hasil yang sangat berbeda (kali ini berjalan 10.000 kali):

Metode 1:

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

Metode 2:

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

Metode 3:

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

Jadi di sini, metode 3 jauh lebih cepat. Hanya pergi untuk menunjukkan ukuran dict Anda akan mempengaruhi metode mana yang Anda pilih.

Catatan: Metode 2 mengembalikan daftar semua nama, sedangkan metode 1 dan 3 hanya mengembalikan kecocokan pertama. Saya belum mempertimbangkan penggunaan memori. Saya tidak yakin apakah metode 3 membuat 2 daftar tambahan (kunci () dan nilai ()) dan menyimpannya dalam memori.

Patrick
sumber
6
Hanya pembaruan: tampaknya dict.values ​​() dan dict.keys () keduanya mengembalikan daftar yang mereferensikan objek dari dict asli, jadi metode 3 juga yang menggunakan memori paling sedikit (hanya membuat dua objek daftar tipis yang membungkus isi dicts, sedangkan yang lain membuat item iterator
Patrick
Saya hanya ingin membandingkannya sendiri, menggulir ke bawah, tapi Anda sudah memilikinya. Terima kasih! Secara teknis seperti yang telah Anda sebutkan metode 2 tidak melakukan hal yang sama persis seperti 1 dan 3 karena mengembalikan semua kecocokan. akan menyenangkan untuk melihat hasil untuk eg return next ([..]).
BluBb_mADe
Catatan penting lain untuk dibuat adalah versi Python. Saya tahu beberapa versi memiliki implementasi metode yang lebih efisien daripada yang lain.
ArtOfWarfare
@ Patrick: semua metode menggunakan referensi langsung ke nilai dan kunci, tidak ada keunggulan memori untuk apa pun. Kecuali dalam Python 3 dan .keys()` .values()kembali tampilan kamus, yang ringan.
Martijn Pieters
53

satu versi baris: (i adalah kamus lama, p adalah kamus terbalik)

Penjelasan: i.keys()dan i.values()mengembalikan dua daftar dengan kunci dan nilai kamus masing-masing. Fungsi zip memiliki kemampuan untuk menyatukan daftar untuk menghasilkan kamus.

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

Peringatan: Ini hanya akan berfungsi jika nilainya hashable dan unik.

penggemar
sumber
Ya, ini akan berhasil: stackoverflow.com/questions/835092/…
The Unfun Cat
17
... dan ketika tidak ada nilai duplikat.
ely
3
Cantik. Wrt komentar di atas, tentu saja itu hanya berfungsi ketika tidak ada nilai duplikat, tetapi kemudian, pertanyaan yang memulai utas ini membuat asumsi bahwa kita memiliki fungsi satu-ke-satu, jadi mengingat asumsi itu, ini adalah yang paling elegan tanggapan jauh.
John Strong
1
memperluas nilai hashable: jika nilai Anda adalah daftar / set, konversikan nilai tersebut agar berfungsi agar (ini masih harus unik).
muon
28
a = {'a':1,'b':2,'c':3}
{v:k for k, v in a.items()}[1]

atau lebih baik

{k:v for k, v in a.items() if v == 1}
Jelen
sumber
5
Bagaimana jika ada kunci lain yang memiliki nilai yang sama dengan a? Mungkin cara pythonic. Tapi bukan ide yang bagus.
7H3 IN5ID3R
Poin bagus, saya menambahkan solusi yang bekerja dengan nilai
Jelen
26
key = next((k for k in my_dict if my_dict[k] == val), None)
faham
sumber
Bisakah saya juga memiliki 'yang lain' di baris yang sama ini? Untuk kasus ketika nilai saya tidak dalam nilai dict
Srishti Gupta
lKey = [k for k, v in lDictionary.iteritems() if v == lValue][0] or 'else-key'
faham
14

Coba satu-baris ini untuk membalikkan kamus:

reversed_dictionary = dict(map(reversed, dictionary.items()))
Johnaphun
sumber
1
Ini berfungsi baik untuk program enkripsi dan dekripsi saya, terima kasih!
Christian R
Sumber
pfabri
@pfabri ???????
johnaphun
13

Saya menemukan jawaban ini sangat efektif tetapi tidak mudah dibaca untuk saya.

Untuk membuatnya lebih jelas, Anda dapat membalikkan kunci dan nilai kamus. Ini membuat nilai kunci dan nilai kunci, seperti yang terlihat di sini .

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

atau

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

yang pada dasarnya sama dengan jawaban yang lain ini .

Rafael Valero
sumber
12

Jika Anda ingin menemukan kunci berdasarkan nilainya, Anda dapat menggunakan pemahaman kamus untuk membuat kamus pencarian dan kemudian menggunakannya untuk menemukan kunci dari nilainya.

lookup = {value: key for key, value in self.data}
lookup[value]
Safia Abdalla
sumber
11

Anda bisa mendapatkan kunci dengan menggunakan dict.keys(), dict.values()dan list.index()metode, lihat contoh kode di bawah ini:

names_dict = {'george':16,'amber':19}
search_age = int(raw_input("Provide age"))
key = names_dict.keys()[names_dict.values().index(search_age)]
Andriy Ivaneyko
sumber
2
Anda tidak menggunakan search_agevar yang ditentukan pada baris berikutnya ... Mungkin Anda harus mengganti valuedengan search_age?
Andersson
2
Saya mendapatkan kesalahan ini: objek 'dict_values' tidak memiliki atribut 'indeks'
Blue_Elephant
@Blue_Elephant, bisakah Anda memberikan potongan kode yang Anda miliki versi kesalahan dan python (juga cetak type(dict_values)akan berguna)?
Andriy Ivaneyko
9

Inilah pendapat saya tentang masalah ini. :) Saya baru saja mulai belajar Python, jadi saya sebut ini:

Solusi "Pemahaman untuk pemula".

#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!
Deithrian
sumber
9
get_key = lambda v, d: next(k for k in d if d[k] is v)
Brett
sumber
Satu kalimat bagus. Namun, isharus digunakan hanya untuk pengujian persamaan lajang ( None, True, Falsedll). Fakta bahwa CPython menggunakan kembali string literal (dan karena itu a = 'foobar'; a is 'foobar'adalah True) merupakan implementasi detail dan tidak boleh diandalkan.
piit79
1
Dan satu lagi komentar: get_keyakan melempar StopIterationjika nilainya tidak ada di kamus - akan lebih baik untuk menggunakan next(..., None)yang akan kembali Nonejika nilainya tidak ditemukan.
piit79
Sedikit modifikasi akan berfungsi jika kamus tidak mengandung elemen tunggal tetapi set:get_first_key = lambda v, d: next((k for k in d if (v in d[k] is not None)), None)
supernova
7

Pertimbangkan menggunakan Panda. Sebagaimana dinyatakan dalam "Python untuk Analisis Data" William McKinney

Cara lain untuk berpikir tentang suatu Seri adalah sebagai dict yang ditetapkan dengan panjang tetap, karena merupakan pemetaan nilai indeks ke nilai data. Ini dapat digunakan dalam banyak konteks di mana Anda mungkin menggunakan dict.

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

Untuk menanyakan seri Anda, lakukan hal berikut:

lookup_list[lookup_list.values == 19]

Yang menghasilkan:

Out[1]: 
amber    19
dtype: int64

Jika Anda perlu melakukan hal lain dengan output yang mengubah jawaban menjadi daftar mungkin berguna:

answer = lookup_list[lookup_list.values == 19].index
answer = pd.Index.tolist(answer)
Axel
sumber
Dia adalah pencipta panda. Dia lebih dikenal sebagai Wes.
Axel
6

Di sini, recover_key mengambil kamus dan nilai untuk ditemukan dalam kamus. Kami kemudian mengulangi kunci dalam kamus dan membuat perbandingan dengan nilai dan mengembalikan kunci tertentu.

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

kita bisa mendapatkan Keydari dictoleh:

def getKey(dct,value):
     return [key for key in dct if (dct[key] == value)]
Sakhri Houssem
sumber
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
patrick
sumber
1
Menggunakan for for dan append jauh lebih lambat daripada pemahaman daftar dan juga lebih lama.
alexpinho98
3

itu dijawab, tetapi bisa dilakukan dengan penggunaan 'peta / pengurangan' yang mewah, misalnya:

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()))
formiaczek
sumber
3

Cat Plus Plus menyebutkan bahwa ini bukan cara kamus dimaksudkan untuk digunakan. Inilah alasannya:

Definisi kamus adalah analog dengan pemetaan dalam matematika. Dalam hal ini, dict adalah pemetaan K (himpunan kunci) ke V (nilai-nilai) - tetapi tidak sebaliknya. Jika Anda mendereferensi dikt, Anda berharap mendapatkan satu nilai yang dikembalikan. Namun, sangat sah untuk kunci yang berbeda untuk memetakan ke nilai yang sama, misalnya:

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

Ketika Anda mencari kunci dengan nilai yang sesuai, Anda pada dasarnya membalik kamus. Tapi pemetaan belum tentu bisa dibalik! Dalam contoh ini, meminta kunci yang sesuai dengan v1 dapat menghasilkan k1 atau k3. Haruskah Anda mengembalikan keduanya? Hanya yang pertama ditemukan? Itu sebabnya indexof () tidak ditentukan untuk kamus.

Jika Anda tahu data Anda, Anda bisa melakukan ini. Tetapi API tidak dapat berasumsi bahwa kamus yang arbitrer tidak dapat dibalik, karenanya tidak ada operasi semacam itu.

Dan Ahlquist
sumber
3

ini adalah pendapat saya. Ini bagus untuk menampilkan beberapa hasil jika Anda membutuhkannya. Jadi saya menambahkan daftar juga

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)

Dan itu saja ...

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

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

Outputnya adalah sebagai berikut:

-> prints george
Jeroen
sumber
[k untuk k, v dalam d.items () jika v == 16]
auro
3

Tidak ada cara mudah untuk menemukan kunci dalam daftar dengan 'mencari' nilainya. Namun, jika Anda tahu nilainya, iterasi melalui tombol, Anda bisa mencari nilai dalam kamus dengan elemen. Jika D [elemen] di mana D adalah objek kamus, sama dengan kunci yang ingin Anda cari, Anda dapat menjalankan beberapa kode.

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

Anda perlu menggunakan kamus dan membalikkan kamus itu. Ini berarti Anda memerlukan struktur data lain. Jika Anda menggunakan python 3, gunakan enummodul tetapi jika Anda menggunakan python 2.7 gunakanenum34 yang kembali porting untuk python 2.

Contoh:

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 
hamidfzm
sumber
2
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            del dic[name]
            return name
Raj Damani
sumber
1
mengapa menghapus kunci dari kamus? itu tidak menjawab pertanyaan
Jean-François Fabre
2

Hanya jawaban saya di lambdadan filter.

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age  , dictionary )
Bishwas Mishra
sumber
1

sudah dijawab, tetapi karena beberapa orang menyebutkan membalik kamus, inilah cara Anda melakukannya dalam satu baris (dengan asumsi pemetaan 1: 1) dan beberapa data berbeda:

python 2.6:

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

2.7+:

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

jika menurut Anda ini bukan 1: 1, Anda masih dapat membuat pemetaan terbalik yang masuk akal dengan beberapa baris:

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

seberapa lambat ini: lebih lambat dari pencarian sederhana, tetapi tidak sepelan yang Anda kira - pada kamus entri 'lurus' 100000, pencarian 'cepat' (yaitu mencari nilai yang seharusnya berada di awal tombol) sekitar 10x lebih cepat daripada membalik seluruh kamus, dan pencarian 'lambat' (menjelang akhir) sekitar 4-5x lebih cepat. Jadi setelah paling banyak sekitar 10 pencarian, itu dibayar untuk dirinya sendiri.

versi kedua (dengan daftar per item) memakan waktu sekitar 2,5x selama versi sederhana.

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

Juga ada beberapa hasil menarik dengan ifilter. Secara teoritis, ifilter harus lebih cepat, karena kita dapat menggunakan itervalues ​​() dan mungkin tidak harus membuat / menelusuri seluruh daftar nilai. Dalam prakteknya, hasilnya ... aneh ...

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

Jadi, untuk offset kecil, secara dramatis lebih cepat daripada versi sebelumnya (2,36 * u * S vs minimum 1,48 * m * S untuk kasus sebelumnya). Namun, untuk offset besar di dekat akhir daftar, itu secara dramatis lebih lambat (15,1 ms vs 1,48 ms yang sama). Penghematan kecil di ujung bawah tidak sebanding dengan biaya di ujung atas, imho.

Corley Brigman
sumber
Saya sangat ingin ini (reversedict = defaultdict (daftar) reversedict [value] .append (key) untuk kunci, nilai di largedict.iteritems ()]) berfungsi, tetapi menggunakan Python 2.7.3, saya mendapatkan kesalahan sintaksis pada kata tersebut 'untuk'
slashdottir
Apakah itu yang sebenarnya Anda ketik? Anda melewatkan sebuah [di dalamnya, jika itu. jika tidak, pastikan ada dua baris, atau letakkan di ;antara keduanya jika tidak.
Corley Brigman
1

Terkadang int () mungkin diperlukan:

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
Denis Kutlubaev
sumber
1

Berikut adalah solusi yang berfungsi baik di Python 2 dan Python 3:

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

Bagian sampai [search_age]membangun kamus terbalik (di mana nilainya adalah kunci dan sebaliknya). Anda dapat membuat metode pembantu yang akan men-cache kamus terbalik ini seperti:

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

atau bahkan lebih umum pabrik yang akan membuat metode pencarian nama berdasarkan usia untuk satu atau lebih dari daftar Anda

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]

sehingga Anda dapat melakukan:

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

Perhatikan bahwa saya berganti nama listmenjadi ages_by_namekarena yang pertama adalah tipe yang sudah ditentukan sebelumnya.

Eold
sumber
1

Ini adalah cara Anda mengakses kamus untuk melakukan apa yang Anda inginkan:

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

tentu saja, nama Anda sangat tidak seperti itu akan mencetak usia, tetapi TIDAK mencetak nama. Karena Anda mengakses dengan nama, itu menjadi lebih dimengerti jika Anda menulis:

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

Lebih baik:

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

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

Untuk beberapa kejadian, gunakan:

keys = [filter( lambda x: dictionary[x] == k  , dictionary )]
Cesar
sumber
*** 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