दिलचस्प पोस्ट
कैसे स्वचालित रूप से एन "अलग" रंग उत्पन्न करने के लिए? फाइल को किस प्रकार से "सोचता है" फाइल के लिए फ़ाइल अनुमतियां पुनर्प्राप्त करें? सी। आईएसडिगिट () और चार। आईएसएनम्बर () के बीच अंतर सी # फिक्स्ड डिवेल में फिट करने के लिए जावास्क्रिप्ट स्केल टेक्स्ट मैं Ubuntu पर OpenSSL पुस्तकालय कैसे स्थापित करूं? प्राइम नंबर के बाद एन प्राइम्स खोजें, बिना किसी फ़ंक्शन का उपयोग किए, जो प्राइमलिटी की जांच करता है पायथन पता पहले से उपयोग में है क्या गिट में फाइलें बदलना / नाम बदलने और उनके इतिहास को बनाए रखना संभव है? एक अजगर MySQLDB खंड में उपयोग के लिए एक सूची imploding एक हैंडलर पोस्टस्टेड की प्रक्रिया को रद्द करना जावास्क्रिप्ट काम का मूल्यांकन कैसे करता है? जावास्क्रिप्ट में = 8 क्यों करता है? कॉलम की गतिशील संख्या में MySQL धुरी पंक्ति नाम के आधार पर संपत्ति मूल्य कैसे प्राप्त करें अक्षम फॉर्म फ़ील्ड डेटा सबमिट नहीं करते हैं

क्या दो डाइक्ट्स को जोड़ने के लिए कोई अजगर तरीका है (दोनों में दिखाई देने वाली कुंजी के लिए मान जोड़ना)?

उदाहरण के लिए मेरे पास दो पत्र हैं:

Dict A: {'a':1, 'b':2, 'c':3} Dict B: {'b':3, 'c':4, 'd':5} 

मुझे 'दो संयोजनों' के संयोजन की एक अजब तरीके की आवश्यकता है, परिणामस्वरूप:

 {'a':1, 'b':5, 'c':7, 'd':5} 

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

वेब के समाधान से एकत्रित समाधान "क्या दो डाइक्ट्स को जोड़ने के लिए कोई अजगर तरीका है (दोनों में दिखाई देने वाली कुंजी के लिए मान जोड़ना)?"

collections.Counter उपयोग करें। collections.Counter :

 >>> from collections import Counter >>> A = Counter({'a':1, 'b':2, 'c':3}) >>> B = Counter({'b':3, 'c':4, 'd':5}) >>> A + B Counter({'c': 7, 'b': 5, 'd': 5, 'a': 1}) 

काउंटर मूल रूप से एक उप-वर्गीय dict , इसलिए आप उन सभी के साथ अभी भी सब कुछ कर सकते हैं, जो आप सामान्य रूप से उस प्रकार के साथ करते हैं, जैसे कि उनकी चाबियाँ और मूल्यों पर पुनरावृत्त।

एक अधिक सामान्य समाधान, जो गैर-संख्यात्मक मानों के लिए भी काम करता है:

 a = {'a': 'foo', 'b':'bar', 'c': 'baz'} b = {'a': 'spam', 'c':'ham', 'x': 'blah'} r = dict(a.items() + b.items() + [(k, a[k] + b[k]) for k in set(b) & set(a)]) 

या अधिक सामान्य:

 def combine_dicts(a, b, op=operator.add): return dict(a.items() + b.items() + [(k, op(a[k], b[k])) for k in set(b) & set(a)]) 

उदाहरण के लिए:

 >>> a = {'a': 2, 'b':3, 'c':4} >>> b = {'a': 5, 'c':6, 'x':7} >>> import operator >>> print combine_dicts(a, b, operator.mul) {'a': 10, 'x': 7, 'c': 24, 'b': 3} 
 >>> A = {'a':1, 'b':2, 'c':3} >>> B = {'b':3, 'c':4, 'd':5} >>> c = {x: A.get(x, 0) + B.get(x, 0) for x in set(A).union(B)} >>> print(c) {'a': 1, 'c': 7, 'b': 5, 'd': 5} 

पहचान: वहाँ (शायद) सबसे अच्छा समाधान कर रहे हैं लेकिन आपको इसे जानना होगा और इसे याद रखना होगा और कभी-कभी आपको यह आशा करना है कि आपका पायथन संस्करण बहुत पुराना नहीं है या जो भी समस्या हो सकती है।

तो सबसे अधिक 'हैकी' समाधान हैं वे महान और छोटे हैं, लेकिन कभी-कभी समझना मुश्किल है, पढ़ने और याद रखना

हालांकि, एक वैकल्पिक जो पहिया को फिर से बदलने का प्रयास करना है – क्यों पहिया बदलते हैं? – आम तौर पर क्योंकि यह सीखने का एक बहुत अच्छा तरीका है (और कभी-कभी सिर्फ इसलिए कि पहले से मौजूद उपकरण वास्तव में ऐसा नहीं करता है कि आप क्या चाहते हैं और / या जिस तरह से आप इसे पसंद करेंगे) और सबसे आसान तरीका अगर आपको पता नहीं है या अपनी समस्या के लिए सही उपकरण याद नहीं है

इसलिए , मैं collections मॉड्यूल (आंशिक रूप से कम से कम) से Counter वर्ग के पहिया को रेइनवेट करने का प्रस्ताव देता हूं:

 class MyDict(dict): def __add__(self, oth): r = self.copy() try: for key, val in oth.items(): if key in r: r[key] += val # You can custom it here else: r[key] = val except AttributeError: # In case oth isn't a dict return NotImplemented # The convention when a case isn't handled return r a = MyDict({'a':1, 'b':2, 'c':3}) b = MyDict({'b':3, 'c':4, 'd':5}) print(a+b) # Output {'a':1, 'b': 5, 'c': 7, 'd': 5} 

संभवत: उसको कार्यान्वित करने के लिए अन्य तरीके होंगे और पहले से ही ऐसा करने के लिए उपकरण हैं लेकिन यह हमेशा कल्पना करना अच्छा होता है कि कैसे चीजें मूल रूप से काम करती हैं।

 myDict = {} for k in itertools.chain(A.keys(), B.keys()): myDict[k] = A.get(k, 0)+B.get(k, 0) 

कोई अतिरिक्त आयात नहीं है!

उनका एक पायथनिक मानक है जिसे ईएएफपी कहा जाता है (अनुमति से अधिक माफी मांगने के लिए आसान)। नीचे कोड उस अजगर मानक पर आधारित है।

 # The A and B dictionaries A = {'a': 1, 'b': 2, 'c': 3} B = {'b': 3, 'c': 4, 'd': 5} # The final dictionary. Will contain the final outputs. newdict = {} # Make sure every key of A and B get into the final dictionary 'newdict'. newdict.update(A) newdict.update(B) # Iterate through each key of A. for i in A.keys(): # If same key exist on B, its values from A and B will add together and # get included in the final dictionary 'newdict'. try: addition = A[i] + B[i] newdict[i] = addition # If current key does not exist in dictionary B, it will give a KeyError, # catch it and continue looping. except KeyError: continue 

संपादित करें: अपने सुधार के सुझावों के लिए जेरोजिक को धन्यवाद

 import itertools import collections dictA = {'a':1, 'b':2, 'c':3} dictB = {'b':3, 'c':4, 'd':5} new_dict = collections.defaultdict(int) for k, v in itertools.chain(dictA.iteritems(), dictB.iteritems()): new_dict[k] += v print dict(new_dict) # OUTPUT {'a': 1, 'c': 7, 'b': 5, 'd': 5} 

या

वैकल्पिक रूप से आप काउंटर का उपयोग कर सकते हैं क्योंकि @ मार्टिजन ने ऊपर उल्लेख किया है।

एक अधिक सामान्य और एक्स्टेंसिबल तरीके से चेक मर्ज किए जाने के लिए यह singledispatch का उपयोग करता है और इसके प्रकारों के आधार पर मूल्यों को विलय कर सकता है।

उदाहरण:

 from mergedict import MergeDict class SumDict(MergeDict): @MergeDict.dispatch(int) def merge_int(this, other): return this + other d2 = SumDict({'a': 1, 'b': 'one'}) d2.merge({'a':2, 'b': 'two'}) assert d2 == {'a': 3, 'b': 'two'} 

निश्चित रूप से Counter() संक्षेप में संक्षेप में ऐसे मामलों में जाने का सबसे अजगर तरीका है, लेकिन केवल अगर यह एक सकारात्मक मूल्य में होता है यहां एक उदाहरण है और जैसा कि आप देख सकते हैं कि B शब्दकोश में c के मूल्य को नकार करने के बाद परिणाम में कोई c नहीं है।

 In [1]: from collections import Counter In [2]: A = Counter({'a':1, 'b':2, 'c':3}) In [3]: B = Counter({'b':3, 'c':-4, 'd':5}) In [4]: A + B Out[4]: Counter({'d': 5, 'b': 5, 'a': 1}) 

ऐसा इसलिए क्योंकि Counter को मुख्य रूप से चलने वाली संख्या (नकारात्मक गणना अर्थहीन) का प्रतिनिधित्व करने के लिए सकारात्मक पूर्णांक के साथ काम करने के लिए डिज़ाइन किया गया था। लेकिन उन उपयोग मामलों में मदद करने के लिए, अजगर न्यूनतम सीमा और प्रकार प्रतिबंधों को निम्नानुसार दस्तावेज करता है:

  • काउंटर क्लास ही एक शब्दकोश उपवर्ग है, जिसमें इसकी चाबियाँ और मूल्यों पर कोई प्रतिबंध नहीं है। मूल्यों का आकलन अंक संख्याओं का प्रतिनिधित्व करना है, लेकिन आप मूल्य क्षेत्र में कुछ भी स्टोर कर सकते हैं।
  • सबसे अधिक most_common() पद्धति की आवश्यकता है कि मूल्य क्रमबद्ध होना चाहिए।
  • इन-प्लेस ऑपरेशंस जैसे कि c[key] += 1 , मूल्य प्रकार को केवल अतिरिक्त समर्थन और घटाव का समर्थन करना चाहिए। तो अंश, फ़्लोट्स, और दशमलव काम करेंगे और नकारात्मक मान समर्थित हैं। वही update() और subtract() लिए भी सच है जो इनपुट और आउटपुट दोनों के लिए नकारात्मक और शून्य मान की अनुमति देता है।
  • मल्टीसेट विधियों को केवल सकारात्मक मूल्यों वाले उपयोग मामलों के लिए डिज़ाइन किया गया है। इनपुट नकारात्मक या शून्य हो सकते हैं, लेकिन केवल सकारात्मक मानों के साथ आउटपुट बनाए जाते हैं। कोई प्रकार की प्रतिबंध नहीं हैं, लेकिन मूल्य प्रकार को इसके अतिरिक्त, घटाव और तुलना का समर्थन करने की आवश्यकता है।
  • elements() विधि पूर्णांक गणना की आवश्यकता है यह शून्य और नकारात्मक गणना को अनदेखा करता है।

इसलिए अपने काउंटर पर संक्षेप के बाद उस समस्या को प्राप्त करने के लिए आप इच्छा आउटपुट प्राप्त करने के लिए Counter.update का उपयोग कर सकते हैं। यह dict.update() तरह काम करता है लेकिन उन्हें बदलने की बजाय गिनती जोड़ती है

 In [24]: A.update(B) In [25]: A Out[25]: Counter({'d': 5, 'b': 5, 'a': 1, 'c': -1}) 
 def merge_with(f, xs, ys): xs = a_copy_of(xs) # dict(xs), maybe generalizable? for (y, v) in ys.iteritems(): xs[y] = v if y not in xs else f(xs[x], v) merge_with((lambda x, y: x + y), A, B) 

आप आसानी से यह सामान्य कर सकते हैं:

 def merge_dicts(f, *dicts): result = {} for d in dicts: for (k, v) in d.iteritems(): result[k] = v if k not in result else f(result[k], v) 

तो यह किसी भी संख्या में ले जा सकता है।

यहाँ मेरा तरीका है:

 dic1 = {'one':1,'two':2} dic2 = {'three':3,'four':4} dic1U2 = {} for i in dic1.keys(): dic1U2[i] = dic1[i] for i in dic2.keys(): dic1U2[i] = dic2[i] print(dic1U2) 

यह समाधान उपयोग करना आसान है, इसका प्रयोग सामान्य शब्दकोश के रूप में किया जाता है, लेकिन आप योग समारोह का उपयोग कर सकते हैं।

 class SumDict(dict): def __add__(self, y): return {x: self.get(x, 0) + y.get(x, 0) for x in set(self).union(y)} A = SumDict({'a': 1, 'c': 2}) B = SumDict({'b': 3, 'c': 4}) # Also works: B = {'b': 3, 'c': 4} print(A + B) # OUTPUT {'a': 1, 'b': 3, 'c': 6} 

इसके अतिरिक्त, कृपया ध्यान दें कि a.update( b ) a + b से 2x तेज है

 from collections import Counter a = Counter({'menu': 20, 'good': 15, 'happy': 10, 'bar': 5}) b = Counter({'menu': 1, 'good': 1, 'bar': 3}) %timeit a + b; ## 100000 loops, best of 3: 8.62 µs per loop ## The slowest run took 4.04 times longer than the fastest. This could mean that an intermediate result is being cached. %timeit a.update(b) ## 100000 loops, best of 3: 4.51 µs per loop 

यह दो शब्दकोशों को विलय करने के लिए एक सरल समाधान है, जहां += मूल्यों पर लागू किया जा सकता है, इसे केवल एक बार शब्दकोश पर पुनरावृत्त करना पड़ता है, मुझे आश्चर्य होता है कि कोई भी यह सुझाव नहीं दे रहा है

 a = {'a':1, 'b':2, 'c':3} dicts = [{'b':3, 'c':4, 'd':5}, {'c':9, 'a':9, 'd':9}] def merge_dicts(merged,mergedfrom): for k,v in mergedfrom.items(): if k in merged: merged[k] += v else: merged[k] = v return merged for dct in dicts: a = merge_dicts(a,dct) print (a) #{'c': 16, 'b': 5, 'd': 14, 'a': 10} 

उपरोक्त समाधान परिदृश्य के लिए महान हैं जहां आपके पास Counter एस की एक छोटी संख्या है यदि आपके पास उनमें से एक बड़ी सूची है, तो ऐसा कुछ बहुत अच्छा है:

 from collections import Counter A = Counter({'a':1, 'b':2, 'c':3}) B = Counter({'b':3, 'c':4, 'd':5}) C = Counter({'a': 5, 'e':3}) list_of_counts = [A, B, C] total = sum(list_of_counts, Counter()) print(total) # Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3}) 

उपर्युक्त समाधान अनिवार्य रूप से Counter संक्षेप में Counter है:

 total = Counter() for count in list_of_counts: total += count print(total) # Counter({'c': 7, 'a': 6, 'b': 5, 'd': 5, 'e': 3}) 

यह वही काम करता है, लेकिन मुझे लगता है कि यह हमेशा यह देखने में मदद करता है कि वह प्रभावी रूप से नीचे क्या कर रहा है।

किसी भी अन्य मॉड्यूल या लिब्स के बिना एक पंक्ति में तीन, एक, बी, सी लिखते हैं

अगर हमारे पास तीन दिशानिर्देश हैं

 a = {"a":9} b = {"b":7} c = {'b': 2, 'd': 90} 

सभी को एक पंक्ति के साथ मर्ज करें और एक डिक्ट ऑब्जेक्ट का उपयोग करें

 c = dict(a.items() + b.items() + c.items()) 

रिटर्निंग

 {'a': 9, 'b': 2, 'd': 90} 

उपयोग करने के लिए सबसे अच्छा है ():

 A = {'a':1, 'b':2, 'c':3} B = {'b':3, 'c':4, 'd':5} Merged = dict(A, **B) Merged == {'a':1, 'b':3, 'c':3, 'd':5}