पायथन डिक्शनरी ऑब्जेक्ट से मुख्य-मूल्य वाले जोड़े का सबसेट निकालें?


313

मेरे पास एक बड़ी शब्दकोश वस्तु है जिसमें कई प्रमुख मूल्य जोड़े हैं (लगभग 16), लेकिन मुझे केवल उनमें से 3 में दिलचस्पी है। इसे प्राप्त करने का सबसे अच्छा तरीका (सबसे छोटा / कुशल / सबसे सुरुचिपूर्ण) क्या है?

सबसे अच्छा मुझे पता है:

bigdict = {'a':1,'b':2,....,'z':26} 
subdict = {'l':bigdict['l'], 'm':bigdict['m'], 'n':bigdict['n']}

मुझे यकीन है कि इससे कहीं अधिक सुरुचिपूर्ण तरीका है। विचार?

जवाबों:


430

तुम कोशिश कर सकते हो:

dict((k, bigdict[k]) for k in ('l', 'm', 'n'))

... या में अजगर ३पायथन संस्करण 2.7 या बाद के संस्करण (इस बात की ओर इशारा करने के लिए फोबियो डिनिज़ का धन्यवाद कि यह 2.7 में भी काम करता है) :

{k: bigdict[k] for k in ('l', 'm', 'n')}

अपडेट: जैसा कि Håvard S बताते हैं, मैं मान रहा हूं कि आपको पता है कि शब्दकोष में होने वाली हैं - यदि आप उस धारणा को बनाने में सक्षम नहीं हैं तो उसका उत्तर देखें । वैकल्पिक रूप से, जैसा कि टिम्बो टिप्पणियों में बताता है , यदि आप एक ऐसी कुंजी चाहते हैं जो bigdictमानचित्र के लिए गायब है None, तो आप कर सकते हैं:

{k: bigdict.get(k, None) for k in ('l', 'm', 'n')}

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

{k: bigdict[k] for k in bigdict.keys() & {'l', 'm', 'n'}}

5
असफल bigdictनहीं होगा अगर शामिल नहीं हैk
Håvard S

7
नीचे की ओर थोड़ा कठोर है कि - यह मेरे संदर्भ से बहुत स्पष्ट लग रहा था कि यह ज्ञात है कि ये शब्द कोश में हैं ...
मार्क लॉन्गेयर

9
{k: bigdict.get(k,None) for k in ('l', 'm', 'n')}उस स्थिति से निपटेंगे जहां कोई निर्दिष्ट कुंजी नए डिक्शनरी में कुंजी की स्थापना करके स्रोत शब्दकोश में गायब है, कोई भी नहीं
timbo

9
@MarkLongair उपयोग के मामले पर निर्भर करता है {k: bigdict [k] में k के लिए ('l', 'm', 'n') यदि k में bigdict} बेहतर हो सकता है, क्योंकि यह केवल उन कुंजियों को संग्रहीत करता है जो वास्तव में मूल्य हैं।
Briford Wylie

6
bigdict.keys() & {'l', 'm', 'n'} ==> bigdict.viewkeys() & {'l', 'm', 'n'} पायथन 2.7 के लिए
kxr

119

थोड़ा छोटा, कम से कम:

wanted_keys = ['l', 'm', 'n'] # The keys you want
dict((k, bigdict[k]) for k in wanted_keys if k in bigdict)

8
एक कुंजी को बाहर करने के वैकल्पिक व्यवहार के लिए +1 अगर यह किसी के लिए इसे स्थापित करने का विरोध करने के रूप में बड़े फैसले में नहीं है।
dhj

1
वैकल्पिक रूप से: dict((k,bigdict.get(k,defaultVal) for k in wanted_keys)यदि आपके पास सभी चाबियां होनी चाहिए।
थॉमस एंड्रयूज

2
यह उत्तर "t" द्वारा सहेजा गया है।
सकुराशिंकिन


16

सभी उल्लिखित विधियों के लिए गति की तुलना:

Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Jan 29 2016, 14:26:21) [MSC v.1500 64 bit (AMD64)] on win32
In[2]: import numpy.random as nprnd
keys = nprnd.randint(1000, size=10000)
bigdict = dict([(_, nprnd.rand()) for _ in range(1000)])

%timeit {key:bigdict[key] for key in keys}
%timeit dict((key, bigdict[key]) for key in keys)
%timeit dict(map(lambda k: (k, bigdict[k]), keys))
%timeit dict(filter(lambda i:i[0] in keys, bigdict.items()))
%timeit {key:value for key, value in bigdict.items() if key in keys}
100 loops, best of 3: 3.09 ms per loop
100 loops, best of 3: 3.72 ms per loop
100 loops, best of 3: 6.63 ms per loop
10 loops, best of 3: 20.3 ms per loop
100 loops, best of 3: 20.6 ms per loop

जैसा कि यह अपेक्षित था: शब्दकोश की समझ सबसे अच्छा विकल्प है।


12

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

अजगर 2 संस्करण:

{k:v for k, v in bigDict.iteritems() if k in ('l', 'm', 'n')}

अजगर 3 संस्करण:

{k:v for k, v in bigDict.items() if k in ('l', 'm', 'n')}

2
... लेकिन अगर बड़ा हुक बड़ा है तो यह अभी भी पूरी तरह से खत्म हो जाएगा (यह एक ओ (एन) ऑपरेशन है), जबकि उलटा सिर्फ 3 आइटम (प्रत्येक ओ (1) ऑपरेशन) को हड़प लेगा।
राउटर बोलस्टरली

1
सवाल केवल 16 कुंजियों के शब्दकोश के बारे में है
मेव

6

शायद:

subdict=dict([(x,bigdict[x]) for x in ['l', 'm', 'n']])

अजगर 3 भी निम्नलिखित का समर्थन करता है:

subdict={a:bigdict[a] for a in ['l','m','n']}

ध्यान दें कि आप शब्दकोश में अस्तित्व के लिए जाँच कर सकते हैं:

subdict=dict([(x,bigdict[x]) for x in ['l', 'm', 'n'] if x in bigdict])

resp। अजगर 3 के लिए

subdict={a:bigdict[a] for a in ['l','m','n'] if a in bigdict}

यदि aनहीं है तोbigdict
Hvvard S

3

ठीक है, यह एक ऐसी चीज है जिसने मुझे कुछ बार परेशान किया है, इसलिए इसे पूछने के लिए जयेश धन्यवाद।

ऊपर दिए गए जवाब किसी भी तरह से एक समाधान के रूप में अच्छे लगते हैं, लेकिन अगर आप अपने पूरे कोड का उपयोग कर रहे हैं, तो यह कार्यक्षमता IMHO को लपेटने के लिए समझ में आता है। इसके अलावा, यहां दो संभावित उपयोग के मामले हैं: एक जहां आप इस बात की परवाह करते हैं कि सभी शब्द मूल शब्दकोश में हैं या नहीं। और एक तुम कहाँ नहीं है दोनों के साथ समान व्यवहार करना अच्छा होगा।

इसलिए, मेरे दो पैसे के मूल्य के लिए, मैं शब्दकोश की एक उप-श्रेणी लिखने का सुझाव देता हूं, उदाहरण के लिए

class my_dict(dict):
    def subdict(self, keywords, fragile=False):
        d = {}
        for k in keywords:
            try:
                d[k] = self[k]
            except KeyError:
                if fragile:
                    raise
        return d

अब आप इसके साथ एक उप-शब्दकोष निकाल सकते हैं

orig_dict.subdict(keywords)

उपयोग के उदाहरण:

#
## our keywords are letters of the alphabet
keywords = 'abcdefghijklmnopqrstuvwxyz'
#
## our dictionary maps letters to their index
d = my_dict([(k,i) for i,k in enumerate(keywords)])
print('Original dictionary:\n%r\n\n' % (d,))
#
## constructing a sub-dictionary with good keywords
oddkeywords = keywords[::2]
subd = d.subdict(oddkeywords)
print('Dictionary from odd numbered keys:\n%r\n\n' % (subd,))
#
## constructing a sub-dictionary with mixture of good and bad keywords
somebadkeywords = keywords[1::2] + 'A'
try:
    subd2 = d.subdict(somebadkeywords)
    print("We shouldn't see this message")
except KeyError:
    print("subd2 construction fails:")
    print("\toriginal dictionary doesn't contain some keys\n\n")
#
## Trying again with fragile set to false
try:
    subd3 = d.subdict(somebadkeywords, fragile=False)
    print('Dictionary constructed using some bad keys:\n%r\n\n' % (subd3,))
except KeyError:
    print("We shouldn't see this message")

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

मूल शब्दकोष:
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x ': 23,' z ': 25}

विषम संख्या वाली कुंजियों से शब्दकोष:
{'a': 0, 'c': 2, 'e': 4, 'g': 6, 'i': 8, 'k': 10, 'm': 12, ' o ': 14,' q ': 16,' s ': 18,' u ': 20,' w ': 22,' y ': 24}

subd2 निर्माण विफल रहता है:
मूल शब्दकोश में कुछ कुंजियाँ नहीं हैं

कुछ खराब कुंजियों का उपयोग करके निर्मित शब्द:
{'b': 1, 'd': 3, 'f': 5, 'h': 7, 'j': 9, 'l': 11, 'n': 13, 'p': 15, 'r': 17, 't': 19, 'v': 21, 'x': 23, 'z': 25}


1
सबक्लासिंग को उप-प्रकार में परिवर्तित होने के लिए एक मौजूदा प्रमुख वस्तु की आवश्यकता होती है, जो महंगी हो सकती है। सिर्फ एक साधारण कार्य क्यों नहीं लिखा subdict(orig_dict, keys, …)?
मुस्तफिल

3

आप भी उपयोग कर सकते हैं map(जो वैसे भी जानने के लिए एक बहुत ही उपयोगी कार्य है):

sd = dict(map(lambda k: (k, l.get(k, None)), l))

उदाहरण:

large_dictionary = {'a1':123, 'a2':45, 'a3':344}
list_of_keys = ['a1', 'a3']
small_dictionary = dict(map(lambda key: (key, large_dictionary.get(key, None)), list_of_keys))

पुनश्च: मैंने .get(key, None)पिछले उत्तर से उधार लिया था :)


1

फिर भी एक और (मैं मार्क लोंगेयर का जवाब पसंद करता हूं)

di = {'a':1,'b':2,'c':3}
req = ['a','c','w']
dict([i for i in di.iteritems() if i[0] in di and i[0] in req])

बड़े
तानाशाह

0

समाधान

from operator import itemgetter
from typing import List, Dict, Union


def subdict(d: Union[Dict, List], columns: List[str]) -> Union[Dict, List[Dict]]:
    """Return a dict or list of dicts with subset of 
    columns from the d argument.
    """
    getter = itemgetter(*columns)

    if isinstance(d, list):
        result = []
        for subset in map(getter, d):
            record = dict(zip(columns, subset))
            result.append(record)
        return result
    elif isinstance(d, dict):
        return dict(zip(columns, getter(d)))

    raise ValueError('Unsupported type for `d`')

उपयोग के उदाहरण

# pure dict

d = dict(a=1, b=2, c=3)
print(subdict(d, ['a', 'c']))

>>> In [5]: {'a': 1, 'c': 3}
# list of dicts

d = [
    dict(a=1, b=2, c=3),
    dict(a=2, b=4, c=6),
    dict(a=4, b=8, c=12),
]

print(subdict(d, ['a', 'c']))

>>> In [5]: [{'a': 1, 'c': 3}, {'a': 2, 'c': 6}, {'a': 4, 'c': 12}]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.