পাইথন অভিধান অবজেক্ট থেকে কী-মান জোড়ার সাবসেটটি বের করবেন?


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 বা পরবর্তী (ধন্যবাদ ফ্যাবিও Diniz যে যে এটা খুব 2.7 কাজ করে প্রতি নির্দেশ জন্য) :

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

আপডেট: হ্যাভার্ড এস হিসাবে উল্লেখ করা হয়েছে, আমি ধরে নিচ্ছি যে আপনি কীগুলি অভিধানে থাকতে হবে তা জানেন - আপনি যদি এই অনুমান করতে সক্ষম না হন তবে তার উত্তর দেখুন । বিকল্পভাবে, টিম্বো মন্তব্যে উল্লেখ করেছে, আপনি যদি 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
হাভার্ড এস

7
এটিকে নিচু করার পক্ষে কিছুটা কঠোর - এটি আমার কাছে প্রসঙ্গ থেকে খুব স্পষ্ট মনে হয়েছিল যে এই কীগুলি অভিধানে রয়েছে তা জানা গেছে ...
মার্ক লংগায়ার

9
{k: bigdict.get(k,None) for k in ('l', 'm', 'n')}পরিস্থিতিটি মোকাবেলা করবে যেখানে নতুন ডিকের মধ্যে কী সেট না করে উত্স অভিধানে একটি নির্দিষ্ট কী অনুপস্থিত রয়েছে
টিম্বো

9
@ মারকলঙ্গায়ার ব্যবহারের ক্ষেত্রে {কে: বিগডিক্ট [কে] কে ইন ইন ('এল', 'এম', 'এন') এর উপর নির্ভর করে যদি কে বিগডিক্টে থাকে better তবে এটি আরও ভাল হতে পারে, কারণ এটি কেবল এমন কীগুলি সংরক্ষণ করে যা আসলে মূল্যবান।
ব্রিফর্ড ওয়াইলি

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
এই উত্তরটি একটি "টি" দ্বারা সংরক্ষিত হয়েছে।
সাকুরাশিংকেন


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

রেস্প। অজগর 3 জন্য

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

যদি ব্যর্থ aহয় নাbigdict
Håvard এস

3

ঠিক আছে, এটি এমন কিছু যা আমাকে কয়েকবার বিরক্ত করেছে, তাই জয়শকে এটি জিজ্ঞাসা করার জন্য আপনাকে ধন্যবাদ।

উপরের উত্তরগুলি কোনওর মতো সমাধানের মতো দুর্দান্ত বলে মনে হচ্ছে, তবে আপনি যদি নিজের কোডটিতে এটি ব্যবহার করেন তবে কার্যকারিতা আইএমএইচও র‌্যাপ করে বোঝা যায়। এছাড়াও, এখানে দুটি সম্ভাব্য ব্যবহারের কেস রয়েছে: একটি যেখানে আপনি সমস্ত কীওয়ার্ড মূল অভিধানে রয়েছেন কিনা তা নিয়ে যত্নশীল হন। এবং যেখানে আপনি না। উভয় সমানভাবে আচরণ করা ভাল হবে।

সুতরাং, আমার দ্বিগুণ দামের জন্য, আমি অভিধানের একটি উপ-শ্রেণীর লেখার পরামর্শ দিচ্ছি, যেমন

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

আপনি যদি উপরের সমস্ত কোড চালনা করেন তবে আপনার নিম্নলিখিত আউটপুটটি দেখতে (এর মতো কিছু) দেখা উচিত (বিন্যাসের জন্য দুঃখিত):

মূল অভিধান:
{'ক': 0, 'সি': 2, 'বি': 1, 'ই': 4, 'ডি': 3, 'জি': 6, 'চ': 5, 'আমি': 8, 'এইচ': 7, 'কে': 10, 'জ': 9, 'এম': 12, 'এল': 11, 'ও': 14, 'এন': 13, 'কিউ': 16, 'পি': 15, 'গুলি': 18, 'আর': 17, 'ইউ': 20, 'টি': 19, 'ডব্লু': 22, 'ভি': 21, 'y': 24, 'x ': 23,' জেড ': 25

বিজোড় সংখ্যাযুক্ত কীগুলি থেকে অভিধান:
{'এ': 0, 'সি': 2, 'ই': 4, 'জি': 6, 'আই': 8, 'কে': 10, 'এম': 12, ' o ': 14,' q ': 16,' s ': 18,' u ': 20,' w ': 22,' y ': 24

সাবডি 2 নির্মাণ ব্যর্থ:
মূল অভিধানে কিছু কী থাকে না

কিছু খারাপ কী ব্যবহার করে অভিধানটি তৈরি করা হয়েছে:
{'বি': 1, 'ডি': 3, 'চ': 5, 'এইচ': 7, 'জ': 9, 'ল': 11, 'এন': 13, 'পি': 15, 'আর': 17, 'টি': 19, 'ভি': 21, 'এক্স': 23, 'জেড': 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}]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.