अजगर शब्दकोश समझ


386

क्या पाइथन (चाबियों के लिए) में एक शब्दकोश समझ बनाना संभव है?

सूची समझ के बिना, आप इस तरह से कुछ का उपयोग कर सकते हैं:

l = []
for n in range(1, 11):
    l.append(n)

हम इसे एक सूची समझ के लिए छोटा कर सकते हैं l = [n for n in range(1, 11)]:।

हालाँकि, मैं कहता हूं कि मैं एक शब्दकोश की कुंजी उसी मूल्य पर सेट करना चाहता हूं। मैं कर सकता हूँ:

d = {}
for n in range(1, 11):
     d[n] = True # same value for each

मैंने यह कोशिश की है:

d = {}
d[i for i in range(1, 11)] = True

हालांकि, मैं एक SyntaxErrorपर मिलता है for

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

d = {}
for n in range(1, 11):
    d[n] = n

क्या यह एक शब्दकोश समझ के साथ संभव है?

d = {}
d[i for i in range(1, 11)] = [x for x in range(1, 11)]

यह भी एक को जन्म देती है SyntaxErrorपर for


3
भविष्य के पाठकों की जानकारी के लिए: NumPy सरणियाँ आपको कई तत्वों को एक मान या सूची की मान सेट करने देती हैं, जिस तरह से आप करने की कोशिश कर रहे हैं। हालांकि अगर आपके पास पहले से ही NumPy का उपयोग करने का कोई कारण नहीं है, तो यह संभवतः इस सुविधा के लिए इसके लायक नहीं है।
डेविड जेड

जवाबों:


520

कर रहे हैं अजगर 2.7+ में शब्दकोश comprehensions , लेकिन वे काफी जिस तरह से आप कोशिश कर रहे हैं काम नहीं करते। सूची की समझ की तरह, वे एक नया शब्दकोश बनाते हैं ; आप किसी मौजूदा शब्दकोश में कुंजी जोड़ने के लिए उनका उपयोग नहीं कर सकते। इसके अलावा, आपको कुंजियों और मूल्यों को निर्दिष्ट करना होगा, हालांकि यदि आप चाहें तो निश्चित रूप से आप एक डमी मूल्य निर्दिष्ट कर सकते हैं।

>>> d = {n: n**2 for n in range(5)}
>>> print d
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

यदि आप उन सभी को True पर सेट करना चाहते हैं:

>>> d = {n: True for n in range(5)}
>>> print d
{0: True, 1: True, 2: True, 3: True, 4: True}

जो आप पूछ रहे हैं वह एक मौजूदा शब्दकोश में एक ही बार में कई कुंजी सेट करने का एक तरीका है। उसके लिए कोई सीधा शॉर्टकट नहीं है। आप या तो लूप कर सकते हैं जैसे कि आप पहले से ही दिखाए गए हैं, या आप नए मूल्यों के साथ एक नया तानाशाही बनाने के लिए एक शब्दकोश समझ का उपयोग कर सकते हैं, और फिर oldDict.update(newDict)पुराने मानों में नए मूल्यों को मर्ज करने के लिए कर सकते हैं।


15
FWIW, कंस्ट्रक्टर की dict.updateतरह ही मुख्य-मूल्य वाले जोड़े के एक पुनरावृत्ति को भी स्वीकार कर सकता हैdict
mgilson

6
ध्यान दें कि यदि आप सभी मानों के साथ एक शब्दकोश बनाते हैं, तो उपयोग करें dict.fromkeys()। इसलिए True, सभी मान सेट करने के लिए , उपयोग करें dict.fromkeys(range(5), True)। ध्यान रखें, मान की प्रतिलिपि नहीं बनाई गई है , इसलिए जब आप एक परिवर्तनशील मूल्य रखते हैं तो आप इससे बचना चाह सकते हैं; यह सभी कुंजियों के बीच साझा किया जाएगा।
मार्टिन पीटर्स

2
नोट: कुंजी एक विधि के परिणाम के रूप में अच्छी तरह से हो सकता है: { n*2 : n for n in range(3) } => {0: 0, 2: 1, 4: 2}। दोनों को एक ही अभिव्यक्ति में किया जा सकता है { n*2 : n*3 for n in range(3) } => { 0: 0, 2: 3, 4: 6 }:।
जहीर

151

आप dict.fromkeysवर्ग विधि का उपयोग कर सकते हैं ...

>>> dict.fromkeys(range(5), True)
{0: True, 1: True, 2: True, 3: True, 4: True}

यह एक शब्दकोश बनाने का सबसे तेज़ तरीका है जहाँ सभी कुंजियाँ समान मान पर चलती हैं।

लेकिन है नहीं परिवर्तनशील वस्तुओं के साथ इस का उपयोग :

d = dict.fromkeys(range(5), [])
# {0: [], 1: [], 2: [], 3: [], 4: []}
d[1].append(2)
# {0: [2], 1: [2], 2: [2], 3: [2], 4: [2]} !!!

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

from collections import defaultdict
d = defaultdict(True)

दूसरे भाग का उत्तर देने के लिए, एक तानाशाही-समझ की आवश्यकता है:

{k: k for k in range(10)}

आपको शायद ऐसा नहीं करना चाहिए, लेकिन आप एक उपवर्ग भी बना सकते हैं, dictजो कुछ हद तक काम करता है जैसे कि defaultdictयदि आप ओवरराइड करते हैं __missing__:

>>> class KeyDict(dict):
...    def __missing__(self, key):
...       #self[key] = key  # Maybe add this also?
...       return key
... 
>>> d = KeyDict()
>>> d[1]
1
>>> d[2]
2
>>> d[3]
3
>>> print(d)
{}

ध्यान दें कि के मामले में d = defaultdict(lambda: True), लैम्ब्डा की आवश्यकता नहीं है क्योंकि ट्रू है (या नहीं) परस्पर योग्य होना चाहिए।
rhbvkleef


22

मैं वास्तव में @mgilson टिप्पणी पसंद करता हूं, क्योंकि यदि आपके पास दो पुनरावृत्तियाँ हैं, तो एक जो चाबियों और दूसरे मूल्यों से मेल खाती है, आप निम्न कार्य भी कर सकते हैं।

keys = ['a', 'b', 'c']
values = [1, 2, 3]
d = dict(zip(keys, values))

दे रही है

d = {'a': 1, 'b': 2, 'c': 3}


4
Dict Comprehension का उपयोग करना:{i:j for i in keys for j in values}
LoMaPh

11

टुपल्स की सूची पर तानाशाही () का उपयोग करें, यह समाधान आपको प्रत्येक सूची में मनमाने मूल्य रखने की अनुमति देगा, इसलिए जब तक वे एक ही लंबाई के न हों

i_s = range(1, 11)
x_s = range(1, 11)
# x_s = range(11, 1, -1) # Also works
d = dict([(i_s[index], x_s[index], ) for index in range(len(i_s))])

12
एक साइड नोट के रूप में, यह वही बात हैd = dict(zip(i_s,x_s))
mgilson

10

डिक्शनरी कॉम्प्रिहेंशन का उपयोग करके किसी सूची में शब्दों की घटना को गिनने के इस उदाहरण पर विचार करें

my_list = ['hello', 'hi', 'hello', 'today', 'morning', 'again', 'hello']
my_dict = {k:my_list.count(k) for k in my_list}
print(my_dict)

और नतीजा है

{'again': 1, 'hi': 1, 'hello': 3, 'today': 1, 'morning': 1}

यह दिलचस्प है, हालांकि सबसे अधिक कुशल नहीं है क्योंकि आप कई बार 'हैलो' की तरह चाबियाँ
गिनेंगे

7

एक सूची समझ का मुख्य उद्देश्य मूल सूची को बदलने या नष्ट किए बिना एक और के आधार पर एक नई सूची बनाना है।

लिखने के बजाय

    l = []
    for n in range(1, 11):
        l.append(n)

या

    l = [n for n in range(1, 11)]

आपको केवल लिखना चाहिए

    l = range(1, 11)

दो शीर्ष कोड ब्लॉक में आप एक नई सूची बना रहे हैं, इसके माध्यम से पुनरावृत्ति कर रहे हैं और प्रत्येक तत्व को वापस कर रहे हैं। यह एक सूची प्रतिलिपि बनाने का सिर्फ एक महंगा तरीका है।

अन्य कुंजी के आधार पर समान मान पर सेट सभी कुंजियों के साथ एक नया शब्दकोश प्राप्त करने के लिए, यह करें:

    old_dict = {'a': 1, 'c': 3, 'b': 2}
    new_dict = { key:'your value here' for key in old_dict.keys()}

जब आप लिखते हैं तो आप एक SyntaxError प्राप्त कर रहे हैं

    d = {}
    d[i for i in range(1, 11)] = True

आप मूल रूप से कह रहे हैं: "मैं अपनी कुंजी सेट कर रहा हूं (i, जो कि रेंज 1, 11) में 'ट्रू' के लिए है और" आई फॉर रेंज में (1, 11) "वैध कुंजी नहीं है, यह सिर्फ एक सिंटैक्स त्रुटि है। यदि कुंजी के रूप में सूचियों का समर्थन करता है, तो आप कुछ ऐसा करेंगे

    d[[i for i in range(1, 11)]] = True

और नहीं

    d[i for i in range(1, 11)] = True

लेकिन सूचियाँ उपलब्ध नहीं हैं, इसलिए आप उन्हें प्रमुख कुंजियों के रूप में उपयोग नहीं कर सकते।


-3

आप की तरह एक सूची हैश नहीं कर सकते। इसके बजाय यह प्रयास करें, यह ट्यूपल्स का उपयोग करता है

d[tuple([i for i in range(1,11)])] = True
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.