मैं एक शब्दकोश में मूल्यों के साथ कुंजियों का आदान-प्रदान कैसे करूं?


97

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

उदाहरण के लिए, मेरा इनपुट है:

a = dict()
a['one']=1
a['two']=2

मैं चाहूंगा कि मेरा आउटपुट:

{1: 'one', 2: 'two'}

स्पष्ट करने के लिए मैं अपना परिणाम निम्नलिखित के बराबर होना चाहूंगा:

res = dict()
res[1] = 'one'
res[2] = 'two'

इसे प्राप्त करने के लिए कोई भी स्वच्छ पायथोनिक तरीका?


1
एक समान प्रश्न के लिए stackoverflow.com/questions/1087694/… देखें , जिसका एक अच्छा जवाब है यदि आप पायथन 3 का उपयोग कर रहे हैं
स्टीफन एडमंड्स

@ स्टेफेन: दूसरा सबसे ज्यादा वोट दिया गया जवाब देखें, यह उसी तरह से है जैसा कि आप जिस प्रश्न से जुड़े हैं, उसी में स्वीकार किया गया है। हालांकि भीड़ ने दूसरे जवाब को पसंद किया ...
Roee Adler

4
पायथन पेरल नहीं है, अजगर रूबी नहीं है। पठनीयता मायने रखती है। विरल घने से बेहतर है। इसे देखते हुए, इन उत्तरों की सभी विधियाँ सिर्फ खराब हैं ™; प्रश्न में से एक सबसे अच्छा तरीका है।
ओ ० '।

जवाबों:


148

अजगर 2:

res = dict((v,k) for k,v in a.iteritems())

पायथन 3 (@erik के लिए धन्यवाद):

res = dict((v,k) for k,v in a.items())

14
हालांकि यह सही प्रतीत होता है, यह केवल कोड के बजाय यह कैसे काम करता है, इसका स्पष्टीकरण जोड़ना अच्छा है।
विल

4
यदि मूल्य अद्वितीय नहीं हैं तो क्या होगा? फिर चाबियाँ एक सूची होनी चाहिए ... उदाहरण के लिए: d = {'a': 3, 'b': 2, 'c': 2} {v: k for k, v in d.iteritems ()} { 2: 'b', 3: 'a'} होना चाहिए {2: ['b', 'c'], 3: 'a'}
Hanan Shteingart

4
@ हननशर्टिंग: ओपी के प्रश्न में वर्णित मूल्य अद्वितीय हैं। कृपया अपने मामले के लिए एक अलग प्रश्न पोस्ट बनाएं (और अधिमानतः इसे अन्य लोगों के लिए यहां लिंक करें)।
लियोरी

python2 कोड काम करता है ... लेकिन सूची की समझ गायब है [और ]। एक सूची समझ की आवश्यकता नहीं है [और ]?
ट्रेवर बॉयड स्मिथ

@TrevorBoydSmith: यह सूची की समझ नहीं है, यह एक जनरेटर अभिव्यक्ति है
लोरी

55
new_dict = dict(zip(my_dict.values(), my_dict.keys()))

4
क्या वास्तव में मूल्य () और कुंजियाँ () समान आदेश देने की गारंटी हैं?
लेन्नर्ट रेग्रोब

1
हाँ, python.org/dev/peps/pep-3106 से आशय है कि विनिर्देश जिस क्रम में .keys (), .values ​​() और .items () द्वारा लौटाए जाते हैं, (जैसा कि यह पायथन में था)। 2.x), क्योंकि यह आदेश सभी तानाशाह से प्राप्त होता है (जो कि संभवतः मनमाना है लेकिन जब तक कि एक तानाशाही संशोधित नहीं हो जाता है) तब तक स्थिर है। लेकिन इस उत्तर के लिए my_dict को दो बार (मानों के लिए, कुंजियों के लिए एक) कॉल की आवश्यकता है। शायद यह आदर्श नहीं है।
सूर्यांग

4
हां, यह उत्तर दो बार तानाशाही से गुजरता है। Sunqiang का उत्तर एक बड़े शब्दकोश के लिए बेहतर है क्योंकि इसमें केवल एक पुनरावृत्ति की आवश्यकता होती है।
कार्ल मेयर

@ कार्ल मेयर: सहमत हैं, इसके अलावा, वे इटर्टूल का उपयोग कर रहे हैं जो बड़े डेटासेट के लिए बहुत बेहतर हैं। हालांकि मुझे आश्चर्य है कि अगर अंतिम तानाशाही () कॉल स्ट्रीमिंग भी है, या अगर यह पहली बार पूरी जोड़े की सूची को इकट्ठा करता है
जेवियर

N> 1e6 (या 1e9) के लिए @CarlMeyer अतिरिक्त रूप से मेमोरी उपयोग वास्तव में बहुत बड़ा होगा ... और यह भी एक गुच्छा धीमा कर देता है।
ट्रेवर बॉयड स्मिथ

47

पायथन 2.7 से, 3.0+ सहित, यकीनन छोटा, अधिक पठनीय संस्करण है:

>>> my_dict = {'x':1, 'y':2, 'z':3}
>>> {v: k for k, v in my_dict.items()}
{1: 'x', 2: 'y', 3: 'z'}

30
In [1]: my_dict = {'x':1, 'y':2, 'z':3}

In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}

3
मूल प्रश्न में नहीं, मैं बस उत्सुक हूं कि क्या होगा यदि आपके पास मूल शब्दकोश में डुप्लिकेट मान हैं और फिर इस विधि के साथ कुंजी / मान स्वैप करें?
आंद्रे मिलर

2
@Andre मिलर: यह विशेष कुंजी की आखिरी घटना लेता है: तानाशाह (((1,3), (1,2))) == {1: 2}
बाल्फा

2
डुप्लिकेट अंतिम सामना किए गए डूप के साथ ओवरराइट हो जाएगा।
क्रिस्टोफर

2
@Andre मिलर: और क्योंकि d.items () एक अनियंत्रित क्रम में आइटम लौटाता है आपको डुप्लिकेट मानों के लिए एक मनमानी कुंजी मिलती है।
चींटियाँ प्लाज्मा जूल

मुझे लगता है कि यह अंतिम कुंजी, मूल्य जोड़ी लेगा जो इसे मिला। यह की तरह है एक [ 'एक्स'] = 3. तो फिर तुम सेट एक [ 'एक्स'] = 4.
रिज़ा

28

आप तानाशाह की समझ का उपयोग कर सकते हैं :

res = {v: k for k, v in a.iteritems()}

संपादित: पायथन 3 के लिए, a.items()इसके बजाय का उपयोग करें a.iteritems()। उन दोनों के बीच मतभेदों के बारे में चर्चा एसओ पर पायथन में पुनरावृत्तियों में पाई जा सकती है ।


18

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

d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.iteritems())
d2
  {'two': 2, 'one': 1}

खबरदार कि अगर आप एक शब्दकोश को 'रिवर्स' नहीं कर सकते हैं

  1. एक से अधिक कुंजी समान मूल्य साझा करती हैं। उदाहरण के लिए {'one':1,'two':1}। नए शब्दकोश में कुंजी के साथ केवल एक आइटम हो सकता है 1
  2. मूल्यों में से एक या अधिक उपलब्ध नहीं है। उदाहरण के लिए {'one':[1]}[1]एक वैध मूल्य है, लेकिन एक वैध कुंजी नहीं है।

विषय पर चर्चा के लिए अजगर मेलिंग सूची पर इस धागे को देखें ।


नोट के बारे में भी +1 यह सुनिश्चित करने के बारे में कि मूल हुकुम में मूल्य अद्वितीय हैं; अन्यथा आप 'उलट' हुकुम में अधिलेखित हो जाएंगे ... और यह (मुझे सिर्फ मेरी लागत का पता चला है) आपके कोड में मुश्किल कीड़े पैदा कर सकता है!
मोनोजोहनी

15

res = dict(zip(a.values(), a.keys()))


4
तानाशाह इस बात की गारंटी नहीं देता है कि उसके मूल्य () और चाबियाँ () उसी क्रम में तत्वों को वापस करेंगे। इसके अलावा, चाबियाँ (), मान () और ज़िप () एक सूची लौटाते हैं, जहां एक पुनरावृत्त पर्याप्त होगा।
लियोरी

19
@ लियोरी: तुम गलत हो। तानाशाह गारंटी देता है कि इसके मूल्य () और कुंजी () एक ही क्रम पर होंगे, यदि आप कॉल को मानों () और कुंजियों () के बीच में संशोधित नहीं करते हैं। प्रलेखन में कहा गया है कि यहां: ("नोट" भाग पढ़ें: docs.python.org/library/stdtypes.html#dict.items ) "यदि आइटम (), कुंजी (), मान (), पुनरावृत्तियाँ (), iterkeys () ), और itervalues ​​() शब्दकोश में कोई हस्तक्षेप संशोधनों के साथ कहा जाता है, सूची सीधे अनुरूप होगा। "
nosklo

1
ठीक है, तो मैं गलत हूँ ... मैंने ऑनलाइन डॉक्स की जाँच नहीं की है। यह इंगित करने के लिए धन्यवाद।
लियोरी

आप इस उत्तर को और अधिक कुशल बनाने के लिए ज़िप के बजाय itteroolertizizip का उपयोग कर सकते हैं।
अलादैर

और iterkeys और itervalues। लेकिन बस iteritems () का उपयोग कर सकते हैं
nosklo

15

वर्तमान प्रमुख उत्तर मान लेते हैं कि मूल्य अद्वितीय हैं जो हमेशा ऐसा नहीं होता है। यदि मूल्य अद्वितीय नहीं हैं तो क्या होगा? आप ढीली जानकारी देंगे! उदाहरण के लिए:

d = {'a':3, 'b': 2, 'c': 2} 
{v:k for k,v in d.iteritems()} 

लौटता है {2: 'b', 3: 'a'}

के बारे 'c'में जानकारी को पूरी तरह से नजरअंदाज कर दिया गया था। आदर्श रूप में यह कुछ ऐसा होना चाहिए था {2: ['b','c'], 3: ['a']}। यह वही है जो नीचे कार्यान्वयन करता है।

अजगर 2.x

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.iteritems():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

अजगर 3.x

def reverse_non_unique_mapping(d):
    dinv = {}
    for k, v in d.items():
        if v in dinv:
            dinv[v].append(k)
        else:
            dinv[v] = [k]
    return dinv

यह सही उत्तर होना चाहिए क्योंकि यह एक अधिक सामान्य मामले को शामिल करता है
लियोन राय

इसके लिए शुक्रिया! मैं अन्य समाधानों के साथ जानकारी खो रहा था।
कैम

14
new_dict = dict( (my_dict[k], k) for k in my_dict)

या इससे भी बेहतर, लेकिन केवल पायथन 3 में काम करता है:

new_dict = { my_dict[k]: k for k in my_dict}

2
वास्तव में Dict Comprehensions ( PEP 274 ) Python 2.7 के साथ भी काम करता है।
आर्सेनी

10

इल्या प्रोकिन की प्रतिक्रिया पर विस्तार करने का एक और तरीका वास्तव में reversedफ़ंक्शन का उपयोग करना है।

dict(map(reversed, my_dict.items()))

संक्षेप में, आपके शब्दकोश का उपयोग (उपयोग करके .items()) किया जाता है, जहां प्रत्येक आइटम एक कुंजी / मान युग्म होता है, और उन वस्तुओं को reversedफ़ंक्शन के साथ स्वैप किया जाता है। जब dictइसे कंस्ट्रक्टर को पास कर दिया जाता है, तो यह उन्हें वैल्यू / किड जोड़े में बदल देता है, जो आप चाहते हैं।


6

जेवियर जवाब के लिए सुधार का सुझाव:

dict(zip(d.values(),d))

इसके बजाय d.keys()आप बस लिख सकते हैंd , क्योंकि यदि आप एक इटैलर के साथ शब्दकोश से गुजरते हैं, तो यह प्रासंगिक शब्दकोश की कुंजी वापस कर देगा।

पूर्व। इस व्यवहार के लिए:

d = {'a':1,'b':2}
for k in d:
 k
'a'
'b'

3

शब्दकोश समझ के साथ आसानी से किया जा सकता है:

{d[i]:i for i in d}

2
dict(map(lambda x: x[::-1], YourDict.items()))

.items()की tuples की सूची देता है (key, value)map()सूची के तत्वों के माध्यम से जाता है और lambda x:[::-1]इसे उलटने के लिए प्रत्येक तत्व (टुपल) पर लागू होता है, इसलिए प्रत्येक ट्यूपल (value, key)नक्शे से बाहर की गई नई सूची में बन जाता है। अंत में, dict()नई सूची से एक तानाशाही बनाता है।


.items () टुपल्स (कुंजी, मान) की एक सूची देता है। नक्शा () सूची के तत्वों के माध्यम से जाता है और lambda x:[::-1]इसे बदलने के लिए प्रत्येक तत्व (टुपल) पर लागू होता है, इसलिए नक्शे से बाहर की गई नई सूची में प्रत्येक ट्यूपल (मूल्य, कुंजी) बन जाता है। अंत में, तानाशाह () नई सूची से एक तानाशाह बनाता है।
इल्या प्रोकिन

1

लूप का उपयोग करना : -

newdict = {} #Will contain reversed key:value pairs.

for key, value in zip(my_dict.keys(), my_dict.values()):
    # Operations on key/value can also be performed.
    newdict[value] = key


1

इन-प्लेस समाधान जोड़ना:

>>> d = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> for k in list(d.keys()):
...     d[d.pop(k)] = k
... 
>>> d
{'two': 2, 'one': 1, 'four': 4, 'three': 3}

Python3 में, यह महत्वपूर्ण है कि आप उपयोग करते हैं list(d.keys())क्योंकि कुंजी का dict.keysएक दृश्य देता है । यदि आप Python2 का उपयोग कर रहे हैं, d.keys()तो पर्याप्त है।


1

हनन का उत्तर सही है क्योंकि यह अधिक सामान्य मामले को कवर करता है (अन्य उत्तर किसी नकलची से अनजान व्यक्ति के लिए भ्रामक हैं)। हनान के जवाब में सुधार सेटडेफॉल्ट का उपयोग कर रहा है:

mydict = {1:a, 2:a, 3:b}   
result = {}
for i in mydict:  
   result.setdefault(mydict[i],[]).append(i)
print(result)
>>> result = {a:[1,2], b:[3]}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.