2012-05-08 13 views
57

मेरे पास है:कैसे उसके संगत मानों के आधार पर कुंजी शब्दकोश फिल्टर करने के लिए

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} 

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

उदाहरण के लिए, मैं परीक्षण करना चाहता हूं कि कौन से शब्दकोश मान 6 से अधिक हैं, और फिर अपनी कुंजी को एक सूची में स्टोर करें। मेरे कोड इस तरह दिखता है:

list = [] 
for c in dictionary: 
    if c > 6: 
     list.append(dictionary[c]) 
print list 

और फिर, एक आदर्श दुनिया में, list सभी कुंजियों जिसका मूल्य 6 से अधिक है की सुविधा होगी। हालांकि, मेरे for लूप केवल चाबियों पर फिर से चल रहा है; मैं इसे मूल्यों में बदलना चाहता हूं!

किसी भी मदद की बहुत सराहना की जाती है। धन्यवाद

+1

इस सवाल का शीर्षक क्या आप वास्तव में (हासिल करना चाहते हैं के बाद से बदल दिया जाना चाहिए और जवाब यह दर्शाते हैं) एक शब्दकोश में संबंधित मानों की कुंजी प्राप्त होती है जिसके लिए एक निश्चित खंड सत्य होता है। कुछ "इसके संबंधित मानों के आधार पर शब्दकोश कुंजी को कैसे फ़िल्टर करें" जैसे कुछ बेहतर विकल्प हो सकता है। – glarrain

उत्तर

81
>>> d = {"foo": 12, "bar": 2, "jim": 4, "bob": 17} 
>>> [k for k, v in d.items() if v > 6] # Use d.iteritems() on python 2.x 
['bob', 'foo'] 

मैं बस भी @glarrain जो मैं अपने आप को आजकल का उपयोग करने के लिए प्रवृत्त खोजने के द्वारा समाधान का प्रदर्शन करने के इस जवाब को अद्यतन करना चाहते हैं।

[k for k in d if d[k] > 6] 

यह पूरी तरह से पार संगत है और .iteritems से एक भ्रामक परिवर्तन की आवश्यकता नहीं है (.iteritems से बचा जाता है अजगर 2 पर स्मृति जो अजगर 3 में तय हो गई है करने के लिए एक सूची बचत) .items करने के लिए।

@ Prof.Falken इस समस्या का समाधान उल्लेख

from six import iteritems 
प्रभावी ढंग से पार संगतता के मुद्दों को ठीक करता है, लेकिन आप की आवश्यकता है जो

पैकेज six

हालांकि मैं पूरी तरह से @glarrain से सहमत नहीं हैं डाउनलोड करने के लिए कि यह समाधान अधिक पठनीय है, जो बहस के लिए है और शायद एक व्यक्तिगत वरीयता है, भले ही पायथन को ऐसा करने का केवल 1 तरीका होना चाहिए। मेरी राय में यह स्थिति पर निर्भर करता है (उदाहरण के लिए। आपके पास एक लंबा शब्दकोश नाम हो सकता है जिसे आप दो बार टाइप नहीं करना चाहते हैं या आप मानों को अधिक पठनीय नाम या कुछ अन्य कारण देना चाहते हैं)

कुछ दिलचस्प समय :

पायथन 2 में, दूसरा समाधान तेज है, पायथन 3 में वे कच्चे गति में लगभग बराबर हैं।


$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 
1000000 loops, best of 3: 0.772 usec per loop 
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.iteritems() if v > 6]' 
1000000 loops, best of 3: 0.508 usec per loop 
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 
1000000 loops, best of 3: 0.45 usec per loop 

$ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 
1000000 loops, best of 3: 1.02 usec per loop 
$ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 
1000000 loops, best of 3: 1.02 usec per loop 

हालांकि इन छोटे शब्दकोशों के लिए ही परीक्षण कर रहे हैं, विशाल शब्दकोशों में मैं बहुत यकीन है कि एक शब्दकोश कुंजी देखने (d[k]) नहीं होने .items बहुत तेजी से होगा हूँ। और इस मामले

$ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 
1 loops, best of 3: 1.75 sec per loop 
$ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.iteritems() if v > 6]' 
1 loops, best of 3: 1.71 sec per loop 
$ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 
1 loops, best of 3: 3.08 sec per loop 
$ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.items() if v > 6]' 
1 loops, best of 3: 2.47 sec per loop 
+0

+1। निश्चित रूप से सबसे अच्छा जवाब IMHO। –

+5

पायथन 2.x के लिए, 'd.iteritems()' बेहतर AFAIK होगा। – hochl

+0

शानदार, धन्यवाद! – Hoops

4

कैसे इस बारे में हो रहा है:

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} 
for val in dictionary.values(): 
    # do something 
+0

यदि ओपी को कोई फर्क नहीं पड़ता है, तो मैं हटाना चाहता हूं मेरा जवाब। @ jamylak यह निश्चित रूप से जाने का रास्ता है। –

36

सिर्फ मूल्यों को प्राप्त करने के लिए, का उपयोग करें, dictionary.values()

कुंजी मान जोड़े के प्राप्त करने के लिए उपयोग करें dictionary.items()

10

शब्दकोश पर items या iteritems का उपयोग करें। कुछ ऐसा:

list = [] 
for k, v in dictionary.iteritems(): 
    if v > 6: 
    list.append(k) 
print list 
2

यह निर्भर करता है कि आप शब्दकोश को संशोधित करना चाहते हैं (आइटम जोड़ें या हटाएं) या नहीं। यदि नहीं तो आप की कोशिश कर सकते:

for value in dictionary.itervalues(): #this returns a generator 
    print "do something with the value" 

वैकल्पिक रूप से, अगर आप शब्दकोश को संशोधित आप मूल्यों की एक प्रति से अधिक पुनरावृति करना चाहिए:

for value in dictionary.values(): #this returns a list of values 
    print "do something with the value" 

आप दोनों कुंजी चाहते हैं, तो और महत्व देता है आप का उपयोग कर जोड़े से अधिक पुनरावृति कर सकते हैं dictionary.iteritems() या dictionary.items()

2

मैं सबसे अच्छा तरीका है (अजगर 3 पर विचार कर माइग्रेशन) यह करने के लिए लगता है

>>> mydict = {'foo': 12, 'bar': 2, 'jim': 4, 'bob': 17} 
>>> [k for k in mydict if mydict[k] > 6] 
['bob', 'foo'] 
है

"सर्वश्रेष्ठ" के लिए मानदंड पठनीयता है।

(अस्वीकरण: मेरा उत्तर अन्य प्रश्न https://stackoverflow.com/a/3744713/556413 को एलेक्स मार्टेली के जवाब में और @ इस सवाल का jamylak की आधारित है)

संबंधित मुद्दे