पायथन - पहले एन कुंजी लौटें: तानाशाही से मूल्य जोड़े


108

निम्नलिखित शब्दकोष पर विचार करें:

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

मैं पहली N कुंजी लौटना चाहता हूं: d जोड़े इस मामले में (N <= 4)। ऐसा करने का सबसे कुशल तरीका क्या है?


1
सावधान। जवाबों में बहुत सी गलत जानकारी दी गई है। मेरे परीक्षण नहीं दिखा एकमात्र समाधान तेजी से है list(d.items())[:4]। सूची () उत्तरों में से कई के लिए अंतर्निहित कार्यान्वयन है।
बसलिता

जवाबों:


114

ऐसी कोई बात नहीं है क्योंकि "पहली n" कुंजी क्योंकि dictयाद नहीं है कि कौन सी कुंजी पहले डाली गई थी।

आप किसी भी n कुंजी-मूल्य जोड़े प्राप्त कर सकते हैं :

n_items = take(n, d.iteritems())

यह व्यंजनोंtake से कार्यान्वयन का उपयोग करता है :itertools

from itertools import islice

def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(islice(iterable, n))

इसे ऑनलाइन काम करते देखें: ideone


पायथन 3.6 के लिए अद्यतन

n_items = take(n, d.items())

42
मेरा मानना ​​है कि पायथन 3 पर लोगों के iteritemsसाथ प्रतिस्थापित किया जाना चाहिएitems
मोनिका हेडडेक

1
@MonicaHeddneck, शानदार, इस टिप्पणी को जोड़ने के लिए धन्यवाद।
कार्ल बेकर

12
यहाँ शुरुआत - take()कहीं भी अजगर कोड आधार का एक हिस्सा है? या, यह विशुद्ध रूप से वह फ़ंक्शन है जिसे आपने अपने उत्तर में परिभाषित किया है? यह पूछने पर कि यह कोड आधार का हिस्सा है, मैं इसे ढूंढ / आयात नहीं कर पा रहा हूं। :)
स्कॉट बोरेन

81

किसी भी चीज़ को पुनः प्राप्त करने का एक बहुत ही कुशल तरीका है कि स्लाइसिंग के साथ सूची या शब्दकोश की समझ को जोड़ा जाए। यदि आपको आइटम ऑर्डर करने की आवश्यकता नहीं है (आप बस n यादृच्छिक जोड़े चाहते हैं), तो आप इस तरह से एक शब्दकोश समझ का उपयोग कर सकते हैं:

# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}

आमतौर पर इस तरह की एक समझ हमेशा "y में लूप के लिए समकक्ष" लूप से अधिक तेज होती है। इसके अलावा, .keys का उपयोग करके () शब्दकोश कुंजियों की एक सूची बनाने के लिए और उस सूची को टुकड़ा करने के लिए जब आप नए शब्दकोश का निर्माण करते हैं तो किसी भी अनावश्यक कुंजी को छूने से बचें।

यदि आपको कुंजियों (केवल मूल्यों) की आवश्यकता नहीं है, तो आप सूची समझ का उपयोग कर सकते हैं:

first2vals = [v for v in mydict.values()[:2]]

यदि आपको उनकी कुंजियों के आधार पर छाँटे गए मानों की आवश्यकता है, तो यह अधिक परेशानी की बात नहीं है:

first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]

या यदि आपको चाबी की आवश्यकता है:

first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}

2
यह एक बेहतर समाधान है यदि आप एन कई कुंजी का चयन करना चाहते हैं: एक शब्दकोश के रूप में मूल्य जोड़े, सूची के रूप में नहीं
fermat4214

1
@ fermat4214 क्या यह एक मुद्दा है, अगर मेरा पूरा शब्दकोश प्रिंट करता है जब मैं इनमें से कोई भी आदेश चलाता हूं?
टेड टेलर ऑफ लाइफ

सूची (mydict) [: 2] व्यर्थ है यदि आपको शब्दकोश को क्रमबद्ध करने की आवश्यकता नहीं है और केवल पहले २ तत्वों की आवश्यकता है। क्या होगा अगर डिक्शनरी में 1 मिलिट्री केवी जोड़े हैं? पूरी बात को एक सूची में बदलना महंगा है। मार्क बायर्स का समाधान ज्यादा बेहतर है।
जेजे

इसका समाधान होना चाहिए!
गुरूवार

14

पायथन के dictआदेश नहीं हैं, इसलिए "पहले एन" कुंजी के लिए पूछना अर्थहीन है।

collections.OrderedDictअगर है कि तुम क्या जरूरत है वर्ग उपलब्ध है। आप कुशलता से इसके पहले चार तत्व प्राप्त कर सकते हैं

import itertools
import collections

d = collections.OrderedDict((('foo', 'bar'), (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')))
x = itertools.islice(d.items(), 0, 4)

for key, value in x:
    print key, value

itertools.isliceआपको आलसी तत्वों को किसी भी पुनरावृत्त से लेने की अनुमति देता है। यदि आप चाहते हैं कि परिणाम पुन: प्रयोज्य हो तो आपको इसे किसी सूची या किसी चीज़ में बदलने की आवश्यकता होगी, जैसे:

x = list(itertools.islice(d.items(), 0, 4))

आलसी नहीं दिख रहा है। 2x को `सूची (d.items ()) [: 4] से अधिक लेता है
बीएसलिटा

12
foo = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
iterator = iter(foo.items())
for i in range(3):
    print(next(iterator))

मूल रूप से, दृश्य (तानाशाही) को पुनरावृति में बदल दें, और फिर इसे अगले () के साथ पुनरावृत्त करें।


2
शानदार जवाब, यह इस पृष्ठ पर एकमात्र उत्तर है जो मेरे लिए काम करता है और पठनीय भी है। इसके अलावा, मैं पायथन 3 के साथ इस काम को सत्यापित कर सकता हूं, जो कुछ पुराने उत्तर नहीं लगते हैं।
cdahms

7

यहां पर नहीं देखा। आदेश नहीं दिया जाएगा, लेकिन सबसे सरल वाक्यविन्यास यदि आपको केवल कुछ तत्वों को एक शब्दकोश से लेने की आवश्यकता है।

n = 2
{key:value for key,value in d.items()[0:n]}

7
मैंने आपको कोड की कोशिश की, लेकिन मुझे यह त्रुटि मिली: TypeError: 'dict_items' object is not subscriptable {key:value for key,value in stocks.items()[0:n]} (स्टॉक मेरे शब्दकोश का नाम है)
मूंदड़ा

2
@ नमोन्द्रा - शब्दकोश आइटम के माध्यम से चलने से पहले सूची में बदलना होगा। उपरोक्त कोड, लाइन कार्य करता है यदि {कुंजी: मान के लिए मूल्य, सूची में मूल्य (d.items ()) [0: n]}
राजेश मप्पू

{ए: एन फॉर (ए, एन) में [x के लिए x में d.items ()] [: 4]}
फैज खफीज़ोव

6

अपने अजगर शब्दकोश से शीर्ष एन तत्वों को प्राप्त करने के लिए एक कोड की निम्नलिखित पंक्ति का उपयोग कर सकते हैं:

list(dictionaryName.items())[:N]

अपने मामले में आप इसे बदल सकते हैं:

list(d.items())[:4]

3

पीईपी 0265 देखें छँटाई शब्दकोशों पर । फिर उपरोक्त उपरोक्त कोड का उपयोग करें।

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

उदाहरण के लिए

import bisect

kvlist = [('a', 1), ('b', 2), ('c', 3), ('e', 5)]
bisect.insort_left(kvlist, ('d', 4))

print kvlist # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]


2

ज़िप का उपयोग करते हुए एक उत्तर जोड़ें,

{k: d[k] for k, _ in zip(d, range(n))}

1

यह इस बात पर निर्भर करता है कि आपके मामले में 'सबसे अधिक कुशल' क्या है।

यदि आप केवल एक विशाल शब्दकोश का अर्ध-यादृच्छिक नमूना चाहते हैं foo, तो इसका उपयोग करें foo.iteritems()और इसमें से उतने ही मान लें जितने की आवश्यकता है, यह एक आलसी ऑपरेशन है जो कुंजियों या वस्तुओं की एक स्पष्ट सूची के निर्माण से बचता है।

यदि आपको पहले कुंजियों को क्रमबद्ध करने की आवश्यकता है, तो कुछ का उपयोग करने का कोई तरीका नहीं है keys = foo.keys(); keys.sort()या sorted(foo.iterkeys()), आपको कुंजियों की एक स्पष्ट सूची बनानी होगी। फिर पहले एन के माध्यम से टुकड़ा या पुनरावृति keys

BTW आप 'कुशल' तरीके की परवाह क्यों करते हैं? क्या आपने अपना कार्यक्रम प्रोफाइल किया? यदि आपने नहीं किया है, तो पहले तरीके को स्पष्ट और आसान समझने के लिए उपयोग करें । संभावना है कि यह एक अड़चन बनने के बिना बहुत अच्छा करेगा।


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

0

आप इसे कई तरीकों से संपर्क कर सकते हैं। यदि आदेश महत्वपूर्ण है तो आप ऐसा कर सकते हैं:

for key in sorted(d.keys()):
  item = d.pop(key)

यदि ऑर्डर चिंता का विषय नहीं है, तो आप ऐसा कर सकते हैं:

for i in range(4):
  item = d.popitem()

पहले स्निपेट में आपको स्पष्टता के valueबजाय संभवतः इसे कॉल करना चाहिए item
एएफएफ

0

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

import operator
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
#itemgetter(0)=sort by keys, itemgetter(1)=sort by values

अब हम शीर्ष 'एन' तत्वों की पुनर्प्राप्ति कर सकते हैं:, इस तरह से विधि संरचना का उपयोग कर:

def return_top(elements,dictionary_element):
    '''Takes the dictionary and the 'N' elements needed in return
    '''
    topers={}
    for h,i in enumerate(dictionary_element):
        if h<elements:
            topers.update({i:dictionary_element[i]})
    return topers

शीर्ष 2 तत्वों को प्राप्त करने के लिए बस इस संरचना का उपयोग करें:

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
d=return_top(2,d)
print(d)

0

पायथन 3 और उससे ऊपर के लिए, पहले n जोड़े का चयन करने के लिए

n=4
firstNpairs = {k: Diction[k] for k in list(Diction.keys())[:n]}

0

एक तानाशाही पर विचार करें

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

from itertools import islice
n = 3
list(islice(d.items(),n))

islice चाल करेंगे :) उम्मीद है कि यह मदद करता है!


0

यह बहुत सुरुचिपूर्ण नहीं हो सकता है, लेकिन मेरे लिए काम करता है:

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

x= 0
for key, val in d.items():
    if x == 2:
        break
    else:
        x += 1
        # Do something with the first two key-value pairs

0

मैंने ऊपर कुछ उत्तरों की कोशिश की है और ध्यान दें कि उनमें से कुछ संस्करण पर निर्भर हैं और संस्करण 3.7 में काम नहीं करते हैं।

मैं यह भी ध्यान देता हूं कि 3.6 के बाद से सभी शब्दकोशों को उस क्रम से क्रमबद्ध किया जाता है जिसमें आइटम डाले जाते हैं।

3.6 के बाद से आदेश दिए जा रहे शब्दकोशों के बावजूद, कुछ कथन जो आप आदेशित संरचनाओं के साथ काम करने की उम्मीद करते हैं, काम नहीं करते हैं।

ओपी सवाल का जवाब जिसने मेरे लिए सबसे अच्छा काम किया।

itr = iter(dic.items())
lst = [next(itr) for i in range(3)]

FYI करें, की तुलना में 5 गुना धीमाlst = list(d.items())[:N]
BSalita
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.