शब्दकोश में मूल्य से कुंजी प्राप्त करें


632

मैंने एक ऐसा फंक्शन बनाया, जो उम्र को देखेगा Dictionaryऔर मिलान नाम दिखाएगा:

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

मुझे पता है कि जिस उम्र की मुझे तुलना करनी है, उसकी तुलना करके मुझे पता नहीं है कि व्यक्ति का नाम कैसे दिखाया जाता है। इसके अतिरिक्त, मैं एक KeyErrorलाइन 5 की वजह से मिल रहा हूं। मुझे पता है कि यह सही नहीं है, लेकिन मैं यह पता नहीं लगा सकता कि इसे पीछे की ओर कैसे खोजा जाए।



क्या आप शब्दकोश में इसकी परिभाषा के आधार पर एक शब्द पाएंगे? नहीं।
जॉसी काल्डेरन

जवाबों:


563

वहां कोई नहीं है। dictइस तरह से इस्तेमाल करने का इरादा नहीं है।

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
इसके Python 3.x list.items()बजाय का list.iteritems()उपयोग किया जाना चाहिए
यूरी पेट्रोव्स्की

63
मैं सहमत नहीं हूं ... एगफ का जवाब अधिक रचनात्मक है। एक पूरी तरह से उचित उपयोग मामला "अनपेक्षित" नहीं है (सूची की समझ वैसे भी इस तरह के उपयोग के मामले में फिट बैठती है)। ए dictअलग-अलग समय पर कई चीजों के लिए हो सकता है; कुंजियों और मूल्यों का एक स्पष्ट अर्थ है, ज़ाहिर है, लेकिन " dictकिसी दिए गए मूल्य के साथ आइटम" एक पूरी तरह से उचित अनुरोध है। जोड़े की एक सूची का उपयोग करने की सिफारिश इस संदर्भ को त्याग देगी कि एक आइटम दूसरे से एक ' परिभाषा ' है, जैसे कि पैरामीटर सूची में ...
लुई मैडॉक्स

1
मैं इस जवाब से सहमत नहीं हूं। तथ्य यह है कि यह एक संभावना है, जैसा कि स्टोनिओ एलसन द्वारा जवाब में दिखाया गया है, इसका मतलब यह नहीं है कि इस तरह का उपयोग करने का इरादा नहीं था। सहायक नहीं है।
ट्रॉपिकलएम्बलर

क्या आप इसकी परिभाषा के आधार पर एक शब्दकोष में शब्द पाएंगे? नहीं। @ ट्रॉपिकलैम्बलर
जोसी काल्डेरॉन

यद्यपि आपके पास एक बिंदु है कि एक शब्द शब्दकोश के लिए एक मानक उपयोग शब्द की परिभाषा = कुंजी और परिभाषा = मूल्य के साथ शब्द की खोज करना है, आज की प्रोग्रामिंग भाषाएं आपको आवश्यक होने पर मूल्य से खोज करने में सक्षम बनाती हैं। यदि आप एक कुंजी के साथ काम कर रहे हैं: वैल्यू पेयर ऑब्जेक्ट (इसे डिक्शनरी कहिए, टपल, जो भी भाषा के लिए नाम है)। अजगर में, यह एक तथ्य है कि आप संबंधित कुंजियों का पता लगाने के लिए संरचना के मूल्यों के माध्यम से अभी भी सूचकांक कर सकते हैं।
उष्णकटिबंधीय काल

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

या अजगर 3.x में:

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

मूल रूप से, यह एक सूची में शब्दकोश के मूल्यों को अलग करता है, आपके पास उस मूल्य की स्थिति पाता है, और उस स्थान पर कुंजी प्राप्त करता है।

पायथन 3 के बारे में keys()और अधिक जानकारी .values(): मैं तानाशाह से मूल्यों की सूची कैसे प्राप्त कर सकता हूं?


23
बहुत अच्छा लग रहा है लेकिन क्या यह हमेशा काम करता है? मेरा मतलब है, क्या करते हैं list.keys()और list.values()कार्य एक ही क्रम में आइटम उत्पन्न करते हैं?
iskorum

17
हां, उन्हें लगातार बने रहने की गारंटी है। इसके अतिरिक्त आदेश की गारंटी है कि पुनरावृत्तियों के माध्यम से न बदलें जब तक कि शब्दकोश को संशोधित नहीं किया जाता है।
विड्राक

9
यह एक अच्छा समाधान प्रतीत होता है, लेकिन इंडेक्स ने केवल एक मान को सही दिया है, इसलिए यदि आप कई बराबर मान रखते हैं, तो यह कई कुंजियों को वापस करना चाहिए?
जेम्स सपम

12
@ArtOfWarfare docs.python.org/3/library/stdtypes.html#dict-views , "यदि कुंजियों, मानों और आइटम विचारों को शब्दकोश में कोई हस्तक्षेप करने वाले संशोधनों के साथ पुनरावृत्त किया जाता है, तो आइटमों का क्रम सीधे अनुरूप होगा।"
विड्रैक

5
@ सिनकोनाटा: यह अभी भी हुड के तहत एक महंगा लूप करता है; लूप सिर्फ indexविधि के अंदर छिपा हुआ है ।
user2357112

252

यदि आप नाम और उम्र दोनों चाहते हैं , तो आपको उसका उपयोग करना चाहिए .items()जो आपको महत्वपूर्ण (key, value)ट्यूपल्स प्रदान करता है:

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

आप forलूप में दो अलग-अलग चर में ट्यूपल को अनपैक कर सकते हैं , फिर आयु का मिलान कर सकते हैं।

यदि आप आम तौर पर उम्र के हिसाब से देख रहे हैं, तो आपको शब्दकोश को उलटने पर भी विचार करना चाहिए, और दो लोगों की उम्र समान नहीं है:

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

तो आप बस कर के एक उम्र के लिए नाम देख सकते हैं

mydict[search_age]

मैं इसे बुला रहा है mydictके बजाय listक्योंकि listका नाम है एक अंतर्निहित प्रकार, और आप कुछ और के लिए है कि नाम का उपयोग नहीं करना चाहिए।

आप एक पंक्ति में दिए गए आयु के साथ सभी लोगों की सूची भी प्राप्त कर सकते हैं:

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

या यदि प्रत्येक आयु वाला एक ही व्यक्ति हो:

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

Noneअगर आपको उस उम्र के साथ कोई नहीं है तो बस आपको देगा ।

अंत में, अगर dictलंबा है और आप पायथन 2 पर हैं, तो आपको इसके जवाब में कैट प्लस के .iteritems()बजाय इसके उपयोग पर विचार करना चाहिए .items(), क्योंकि इसके लिए सूची की प्रतिलिपि बनाने की आवश्यकता नहीं है।


9
सही, लेकिन यदि आप रैखिक खोज करने जा रहे हैं, तो आप dictजोड़े की सूची के साथ बदल सकते हैं ।
फ्रेड फू

9
जब तक कि आपकी सामान्य क्रिया उम्र को नाम से नहीं देख रही है, इस मामले में dictसमझ में आता है।
21

2
यह अजीब लगता है कि प्रत्येक आयु के साथ केवल एक ही व्यक्ति है, जबकि दूसरी ओर, प्रत्येक व्यक्ति के लिए एक ही उम्र के लिए यह पूरी तरह से तर्कसंगत है।
1

@ डनीड यस, लेकिन समस्या को आसानी से सामान्यीकृत किया जा सकता है। उदाहरण के लिए, आपके पास विशिष्ट कुंजियों और उनके संबंधित विशिष्ट मानों के साथ एक लुक अप टेबल हो सकती है। फिर आप चीजों को सममित रूप से देख सकते हैं value --> keyयाkey --> value
pfabri

67

मैंने सोचा कि यह बताना दिलचस्प होगा कि कौन से तरीके सबसे तेज़ हैं, और किस परिदृश्य में:

यहाँ कुछ परीक्षण मैंने चलाए (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)]

profile.run()प्रत्येक विधि पर परिणाम 100000 बार:

विधि 1:

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

विधि 2:

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

विधि 3:

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

तो इससे पता चलता है कि एक छोटे से हुकुम के लिए, विधि 1 सबसे तेज है। यह सबसे अधिक संभावना है क्योंकि यह पहला मैच लौटाता है, जैसा कि सभी मैचों जैसे कि विधि 2 (नीचे नोट देखें) के विपरीत है।


दिलचस्प है, 2700 प्रविष्टियों के साथ मेरे पास एक तानाशाही पर एक ही परीक्षण करना, मुझे काफी अलग परिणाम मिलते हैं (यह समय 10000 बार चलता है):

विधि 1:

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

विधि 2:

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

विधि 3:

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

तो यहाँ, विधि 3 बहुत तेज है। बस अपने हुक्म का आकार दिखाने के लिए जाता है कि आप किस विधि का चयन करेंगे।

नोट: विधि 2 सभी नामों की एक सूची देता है , जबकि विधियाँ 1 और 3 केवल पहले मैच में लौटती हैं । मैंने स्मृति उपयोग पर विचार नहीं किया है। मुझे यकीन नहीं है कि अगर विधि 3 2 अतिरिक्त सूचियाँ (चाबियाँ) और मूल्य ()) बनाती है और उन्हें मेमोरी में संग्रहीत करती है।


6
बस एक अद्यतन: ऐसा लगता है कि तानाशाह। जो डिकेट की सामग्री को लपेटते हैं, जबकि अन्य लोग इटेरेटर आइटम बनाते हैं
पैट्रिक

मैं बस इसे खुद बेंचमार्क करना चाहता था, नीचे स्क्रॉल किया, बाम वहाँ आपके पास है। धन्यवाद! तकनीकी रूप से जैसा कि आपने पहले ही बताया है कि विधि 2 में 1 और 3 जैसी सटीक बात नहीं है क्योंकि यह सभी मैच लौटाता है। अगले (जैसे [..] वापसी के लिए परिणाम देखने के लिए अच्छा होगा।
BluBb_mADe

एक और महत्वपूर्ण नोट पायथन संस्करण है। मुझे पता है कि कुछ संस्करणों में दूसरों की तुलना में विधियों का अधिक कुशल कार्यान्वयन है।
ArtOfWarfare

@ पैट्रिक: सभी विधियां मूल्यों और कुंजियों के लिए सीधे संदर्भ का उपयोग करती हैं, किसी को कोई स्मृति लाभ नहीं है। पाइथन 3 और .keys()` .values()रिटर्न डिक्शनरी व्यू को छोड़कर , जो हल्के वजन वाले हैं।
मार्टिन पीटर्स

53

एक पंक्ति संस्करण: (मैं एक पुराना शब्दकोश है, पी एक उलटा शब्द है)

स्पष्टीकरण: i.keys()और i.values()दो सूचियों को क्रमशः शब्दकोश की कुंजी और मान के साथ लौटाता है। ज़िप फ़ंक्शन में डिक्शनरी बनाने के लिए सूचियों को एक साथ जोड़ने की क्षमता है।

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

चेतावनी: यह तभी काम करेगा, जब मूल्य धुँधले और अनोखे हों।


हां, यह काम करेगा: stackoverflow.com/questions/835092/…
द अनफिन कैट

17
... और जब कोई डुप्लिकेट मान नहीं हैं।
Ely

3
सुंदर। ऊपर टिप्पणी लिखें, निश्चित रूप से यह केवल तभी काम करता है जब कोई डुप्लिकेट मान नहीं होता है, लेकिन फिर, इस थ्रेड को शुरू करने वाला प्रश्न यह धारणा बनाता है कि हमारे पास एक-से-एक फ़ंक्शन है, इसलिए उस धारणा को देखते हुए, यह सबसे सुरुचिपूर्ण है दूर तक प्रतिक्रिया।
जॉन स्ट्रांग

1
हैशेबल वैल्यू पर विस्तार करना: यदि आपके मान लिस्ट / सेट हैं, तो उन्हें इस कार्य के लिए टपल में बदल दें (उन्हें अभी भी अद्वितीय होने की आवश्यकता है)।
मुईन

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

या और अच्छा

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

5
क्या होगा यदि एक और कुंजी है जो एक ही मूल्य रखती है? पाइथोनिक तरीका हो सकता है। लेकिन एक अच्छा विचार नहीं है।
7H3 IN5ID3R

अच्छा बिंदु, मैं समाधान जो nonunique मूल्यों के साथ काम करता है जोड़ा
Jelen

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

क्या मैं भी इसी लाइन में 'और' हो सकता हूं? उस मामले के लिए जब मेरा मूल्य तानाशाहों में नहीं है
सृष्टि गुप्ता

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

14

शब्दकोश को उलटने के लिए इस वन-लाइनर को आज़माएं:

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

1
यह मेरे एन्क्रिप्शन और डिक्रिप्शन प्रोग्राम के लिए बहुत अच्छा काम किया, धन्यवाद!
क्रिश्चियन आर


@ पफब्री ???????
जॉनफुन

13

मुझे यह उत्तर बहुत प्रभावी लगा लेकिन मेरे लिए पढ़ना बहुत आसान नहीं था।

इसे और अधिक स्पष्ट करने के लिए आप एक शब्दकोश की कुंजी और मूल्य को उल्टा कर सकते हैं। यह कुंजी मान और मान कुंजी बना रहा है, जैसा कि यहां देखा गया है

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

या

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

जो अनिवार्य रूप से वही है जो यह अन्य उत्तर है


12

यदि आप मान द्वारा कुंजी ढूंढना चाहते हैं, तो आप लुकअप शब्दकोश बनाने के लिए एक शब्दकोश समझ का उपयोग कर सकते हैं और फिर मूल्य से कुंजी को खोजने के लिए इसका उपयोग कर सकते हैं।

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

11

आप उपयोग करके कुंजी प्राप्त कर सकते हैं dict.keys(), dict.values()और list.index()विधियाँ, नीचे दिए गए कोड नमूने देख सकते हैं:

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

2
आप परिभाषित का उपयोग नहीं करते search_ageअगली पंक्ति पर वर ... शायद तुम बदल दिया जाना चाहिए valueके साथ search_age?
एंडरसन

2
मुझे यह त्रुटि मिलती है: 'dict_values' ऑब्जेक्ट में कोई विशेषता नहीं है 'सूचकांक'
Blue_Elephant

@Blue_Elephant क्या आप कोड स्निपेट प्रदान कर सकते हैं जो आपको त्रुटि और अजगर संस्करण मिला है (प्रिंट भी type(dict_values)उपयोगी होगा)?
एंड्री इवानियको

9

यहाँ इस समस्या पर मेरा विचार है। :) मैंने अभी पायथन सीखना शुरू किया है, इसलिए मैं इसे कॉल करता हूं:

"अंडरस्टैंडिंग फॉर बिगिनर्स" समाधान।

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

अच्छा एक लाइनर। हालांकि, isकेवल (एकमात्र की समानता के परीक्षण के लिए इस्तेमाल किया जाना चाहिए None, True, Falseआदि)। तथ्य यह है कि CPython स्ट्रिंग शाब्दिक पुनः उपयोग कर लेता है (और इसलिए a = 'foobar'; a is 'foobar'है True) एक कार्यान्वयन विस्तार है और पर भरोसा नहीं किया जाना चाहिए।
piit79

1
और एक और टिप्पणी: get_keyफेंक देंगे StopIterationअगर मूल्य शब्दकोष में मौजूद नहीं है - तो इसका उपयोग next(..., None)करना बेहतर होगा जो Noneमूल्य नहीं मिला तो वापस आ जाएगा ।
piit79 12

एक मामूली संशोधन काम करेगा अगर शब्दकोश में एकल तत्व नहीं हैं, लेकिन सेट हैं:get_first_key = lambda v, d: next((k for k in d if (v in d[k] is not None)), None)
सुपरनोवा

7

पंडों का उपयोग करने पर विचार करें। जैसा कि विलियम मैकिनी के "पायथन फॉर डेटा एनालिसिस" में कहा गया है

श्रृंखला के बारे में सोचने का एक और तरीका एक निश्चित-लंबाई के रूप में है, जो आदेश दिया गया है, क्योंकि यह डेटा मूल्यों के लिए सूचकांक मूल्यों का मानचित्रण है। इसका उपयोग कई संदर्भों में किया जा सकता है जहां आप एक तानाशाही का उपयोग कर सकते हैं।

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

अपनी श्रृंखला को क्वेरी करने के लिए निम्न कार्य करें:

lookup_list[lookup_list.values == 19]

कौन सी पैदावार:

Out[1]: 
amber    19
dtype: int64

यदि आपको आउटपुट को सूची में बदलने के साथ कुछ और करने की आवश्यकता है तो यह उपयोगी हो सकता है:

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

वह पांडा का निर्माता है। वह अधिक सामान्यतः वेस के रूप में जाना जाता है, हालांकि।
एक्सल

6

यहाँ, Recovery_key शब्दकोश में खोजने के लिए शब्दकोश और मूल्य लेता है। हम तब शब्दकोश में कुंजियों पर लूप करते हैं और मूल्य के साथ तुलना करते हैं और उस विशेष कुंजी को वापस करते हैं।

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

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
लूप और एपेंड के लिए उपयोग करना सूची समझ से बहुत धीमा है और यह अधिक लंबा भी है।
एलेक्सपिनो98


3

इसका उत्तर दिया गया है, लेकिन इसे फैंसी 'मैप / कम' उपयोग के साथ किया जा सकता है, जैसे:

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

कैट प्लस प्लस ने उल्लेख किया कि यह ऐसा नहीं है कि कैसे शब्दकोश का उपयोग करने का इरादा है। यहाँ पर क्यों:

एक शब्दकोश की परिभाषा गणित में मानचित्रण के अनुरूप है। इस मामले में, एक तानाशाह वी (मूल्यों) के लिए K (कुंजी का सेट) की मैपिंग है - लेकिन इसके विपरीत नहीं। यदि आप एक तानाशाही को समाप्त करते हैं, तो आप एक मूल्य वापस पाने की उम्मीद करते हैं। लेकिन, विभिन्न कुंजियों के लिए एक ही मूल्य पर मैप करना पूरी तरह से कानूनी है, जैसे:

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

जब आप इसकी कीमत के आधार पर एक कुंजी को देखते हैं, तो आप अनिवार्य रूप से शब्दकोश को बदल रहे हैं। लेकिन एक मैपिंग जरूरी नहीं कि उलटा हो! इस उदाहरण में, v1 से संबंधित कुंजी के लिए पूछना k1 या k3 प्राप्त कर सकता है। क्या आपको दोनों लौटाने चाहिए? बस पहला वाला मिला? इसीलिए indexof () शब्दकोशों के लिए अपरिभाषित है।

यदि आप अपना डेटा जानते हैं, तो आप ऐसा कर सकते हैं। लेकिन एक एपीआई यह नहीं मान सकता है कि एक मनमाना शब्दकोश उलटा है, इसलिए इस तरह के ऑपरेशन की कमी है।


3

यहाँ इस पर मेरा लेना है। यदि आपको एक की जरूरत है तो यह कई परिणामों को प्रदर्शित करने के लिए अच्छा है। इसलिए मैंने सूची भी जोड़ दी

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)

और बस...


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

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

आउटपुट इस प्रकार है:

-> prints george

[k के लिए k, v में d.items () if v == 16]
ऑरो

3

मूल्य को 'देख कर' सूची में एक कुंजी खोजने का कोई आसान तरीका नहीं है। हालांकि, यदि आप मूल्य जानते हैं, तो कुंजियों के माध्यम से पुनरावृत्ति करते हुए, आप तत्व द्वारा शब्दकोश में मान देख सकते हैं। यदि D [एलिमेंट] जहां डी एक डिक्शनरी ऑब्जेक्ट है, तो उस कुंजी के बराबर है जिसे आप देखने की कोशिश कर रहे हैं, तो आप कुछ कोड निष्पादित कर सकते हैं।

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

आपको एक शब्दकोश का उपयोग करने की आवश्यकता है और उस शब्दकोश को उल्टा करना होगा। इसका मतलब है कि आपको एक और डेटा संरचना की आवश्यकता है। यदि आप अजगर 3 में हैं, enumतो मॉड्यूल का उपयोग करें लेकिन यदि आप अजगर 2.7 का उपयोग कर रहे हैं enum34जो कि अजगर 2 के लिए वापस पोर्ट किया गया है।

उदाहरण:

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 



1

पहले से ही उत्तर दिया गया है, लेकिन चूंकि कई लोगों ने शब्दकोश को उलटने का उल्लेख किया है, यहां बताया गया है कि आप इसे एक पंक्ति में कैसे करते हैं (1: 1 मानचित्रण) और कुछ विभिन्न पूर्ण डेटा:

अजगर 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 नहीं है, तो आप अभी भी एक युगल लाइनों के साथ एक उचित रिवर्स मैपिंग बना सकते हैं:

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

यह कितना धीमा है: एक साधारण खोज की तुलना में धीमा, लेकिन लगभग उतना नहीं जितना आप सोचते हैं - 'सीधे' 100000 प्रविष्टि डिक्शनरी पर, एक 'तेज' खोज (यानी एक मूल्य की तलाश में जो कुंजी में जल्दी होनी चाहिए) पूरे शब्दकोश को उलटने की तुलना में लगभग 10x तेज था, और 'धीमी' खोज (अंत की ओर) लगभग 4-5x तेज थी। तो लगभग 10 लुकअप के बाद, यह खुद के लिए भुगतान किया जाता है।

दूसरा संस्करण (प्रति आइटम की सूची के साथ) लगभग 2.5x सरल संस्करण के रूप में लंबे समय तक ले जाता है।

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

इफिल्टर के साथ कुछ दिलचस्प परिणाम भी मिले। सैद्धांतिक रूप से, इफिल्टर तेज होना चाहिए, इसमें हम itervalues ​​() का उपयोग कर सकते हैं और संभवतः पूरे मान सूची के माध्यम से बनाना / जाना नहीं है। व्यवहार में, परिणाम थे ... विषम ...

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

इसलिए, छोटे ऑफसेट्स के लिए, यह किसी भी पिछले संस्करण की तुलना में नाटकीय रूप से तेज था (2.36 * u * S बनाम पिछले मामलों के लिए न्यूनतम 1.48 * m * S)। हालाँकि, सूची के अंत के पास बड़े ऑफ़सेट्स के लिए, यह नाटकीय रूप से धीमा था (15.1ms बनाम वही 1.48mS)। कम अंत में छोटी बचत उच्च अंत, इम्हो में लागत के लायक नहीं है।


मैं बहुत चाहता हूं कि यह (उलटफेर = डिफाल्टडिक्ट (सूची) उलटा [मूल्य] .append (कुंजी) कुंजी के लिए, लार्जिक्ट में मान। मानदंड) ()] काम करने के लिए, लेकिन पायथन 2.7.3 का उपयोग करते हुए, मैं शब्द पर वाक्य रचना त्रुटि करता हूं। 'फॉर'
स्लैशडॉटिर

क्या आपने वास्तव में टाइप किया है? आप इसे याद कर रहे हैं [, अगर यह है। अन्यथा, सुनिश्चित करें कि यह दो लाइनों पर है, या ;यदि ऐसा नहीं है तो उनके बीच में रखें।
Corley Brigman

1

कभी-कभी int () की आवश्यकता हो सकती है:

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

यहाँ एक समाधान है जो पायथन 2 और पायथन 3 दोनों में काम करता है:

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

तब तक जब तक [search_age]कि रिवर्स डिक्शनरी नहीं बनती (जहाँ मान कुंजियाँ और इसके विपरीत हैं)। आप एक सहायक विधि बना सकते हैं जो इस उल्टे शब्द को इस तरह कैश करेगी:

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

या इससे भी अधिक आम तौर पर एक कारखाना जो आपकी एक या अधिक सूचियों के लिए एक उप-आयु नाम लुकअप विधि का निर्माण करेगा

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]

तो आप कर पाएंगे:

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

ध्यान दें कि मैं नाम दिया listकरने ages_by_nameके बाद से पूर्व एक पूर्वनिर्धारित प्रकार है।


1

यह है कि आप क्या चाहते हैं करने के लिए शब्दकोश का उपयोग:

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

बेशक, आपके नाम इतने बंद हैं कि ऐसा लग रहा है कि यह एक उम्र का मुद्रण होगा, लेकिन यह नाम को प्रिंट करता है। चूंकि आप नाम से पहुंच रहे हैं, अगर आप लिखते हैं तो यह अधिक समझ में आता है:

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

और भी बेहतर:

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.

कई घटनाओं के लिए उपयोग करें:

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

*** NameError: global name 'dictionary' is not defined
बिश्व मिश्रा

filter( lambda x, dictionary=dictionary, search_age=int(search_age): dictionary[x] == search_age , dictionary )
बिस्वास मिश्रा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.