एक शब्दकोश मानचित्रण को उल्टा / उल्टा करें


जवाबों:


923

पायथन 2.7.x के लिए

inv_map = {v: k for k, v in my_map.iteritems()}

पायथन 3+ के लिए:

inv_map = {v: k for k, v in my_map.items()}

4
हाल ही में अजगर 2.7.x संस्करणों में my_map.items()के रूप में अच्छी तरह से काम करता है
Valentin

29
यह काम करेगा सिवाय इसके कि यह काम नहीं करेगा अगर मूल्यों में एकता नहीं है। उस स्थिति में आप कुछ प्रविष्टियों को ढीला कर देंगे
gabuzo


2
हां, एक कार्यान्वयन विवरण के रूप में। The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon। इसकी कोई गारंटी नहीं है कि यह उसी तरह रहेगा ताकि कोड Dictउसी तरह के व्यवहार पर निर्भर न हो OrderedDict
मैटियास

9
@ माटियास, यह पायथन 3.6 के लिए सच है। संस्करण 3.7 के लिए आदेश-संरक्षण आधिकारिक है: mail.python.org/pipermail/python-dev/2017-Deuled/151283.html । BDFL ने ऐसा कहा।
इंटरडिस्ट

174

यह मानते हुए कि तानाशाह में मूल्य अद्वितीय हैं:

dict((v, k) for k, v in my_map.iteritems())

22
मूल्यों को भी धोने योग्य होना चाहिए
जॉन ला रोय

30
@ बटंस 840: यदि मूल्य अद्वितीय नहीं हैं, तो वैसे भी शब्दकोश का कोई अनूठा उलटा नहीं है या, अन्य शब्दों के साथ, inverting का कोई मतलब नहीं है।
Wrzlprmft

2
@ Buttons840 मान के लिए केवल अंतिम कुंजी दिखाई देगी। iteritems()उत्पादन के आदेश पर शायद कोई गारंटी नहीं है , इसलिए यह माना जा सकता है कि एक अनियंत्रित कुंजी को एक गैर-अनूठे मूल्य के लिए सौंपा जाएगा, एक तरह से जो कुछ शर्तों के तहत जाहिरा तौर पर प्रतिलिपि प्रस्तुत करने योग्य होगा, लेकिन सामान्य रूप से ऐसा नहीं है।
एवगेनी सर्गेव

2
ध्यान दें, निश्चित रूप से, कि पायथन 3 में अब कोई iteritems()विधि नहीं है और यह दृष्टिकोण काम नहीं करेगा; items()इसके बजाय उपयोग के रूप में स्वीकार किए जाते हैं उत्तर में दिखाया गया है। इसके अलावा, एक शब्दकोश की समझ इस कॉलिंग की तुलना में बेहतर होगी dict
मार्क एमी

5
@Wrzlprmft गैर-विशिष्ट मानों के मामले में व्युत्क्रम के लिए एक प्राकृतिक परिभाषा है। हर मूल्य को कुंजी के सेट के लिए मैप किया जाता है, जो इसे ले जाता है।
सिंह

135

यदि मूल्य my_mapअद्वितीय नहीं हैं:

inv_map = {}
for k, v in my_map.iteritems():
    inv_map[v] = inv_map.get(v, [])
    inv_map[v].append(k)

56
... या सिर्फ inv_map.setdefault (v, [])। परिशिष्ट (के)। मैं एक डिफ़ॉल्ट फैनबॉय हुआ करता था, लेकिन फिर मैंने कई बार एक खराब कर दिया और निष्कर्ष निकाला कि वास्तव में स्पष्ट रूप से निहित से बेहतर है।
alsuren

बहु-मानचित्र के लिए यह उत्तर गलत है, यहाँ संलग्न करना बेकार है क्योंकि मूल्य हर बार खाली सूची पर रीसेट हो जाता है, सेट_डेफॉल्ट का उपयोग करना चाहिए
यारोस्लाव

1
@YaroslavBulatov नहीं, कोड के रूप में यहाँ दिखाया गया है टूटा नहीं है - inv_map.get(v, [])अगर पहले से ही एक है, तो एक खाली सूची में रीसेट नहीं करता है, तो पहले से ही जोड़ा सूची लौटाता है। setdefaultहालांकि अभी भी प्रेटियर होगा।
मार्क अमेरी

10
एक सेट यहाँ अधिक समझ में आता है। चाबियाँ हैं (शायद) धोने योग्य, और कोई आदेश नहीं है। inv_map.setdefault(v, set()).add(k)
आर्टीयर

1
Python3 में, के my_map.items()बजाय का उपयोग करें my_map.iteritems()
एपिटश

42

अपनी मैपिंग के प्रकार को सुरक्षित रखते हुए ऐसा करने के लिए (यह मानते हुए कि यह एक dictया एक dictउपवर्ग है))

def inverse_mapping(f):
    return f.__class__(map(reversed, f.items()))

4
चतुर यह हो सकता है, लेकिन यह काम नहीं करता है जब मूल शब्दकोश में एक से अधिक कुंजी का समान मूल्य होता है।
राफेल_एस्पेरिकेटा

1
@ राफेल_एस्पेरिकुइट इस सवाल के किसी भी संभावित उत्तर के बारे में सच है, क्योंकि दोहराए गए मानों वाला नक्शा उल्टा नहीं है।
मार्क अमेरी

2
@Mark_Amery यह एक अर्थ में, अधिक सामान्यतः उल्टा हो सकता है। उदाहरण के लिए: D = {1: [1, 2], 2: [2, 3], 3: [1]}, दिनव = {1: [1, 3], 2: [1, 2], 3: [2]}। D उदाहरण के लिए एक शब्दकोश है {अभिभावक: बच्चे}, जबकि दीनव {बच्चा: माता-पिता} शब्दकोश है।
राफेल_एस्पेरिकेटा

36

इसे इस्तेमाल करे:

inv_map = dict(zip(my_map.values(), my_map.keys()))

(ध्यान दें कि शब्दकोश विचारों पर पायथन डॉक्स स्पष्ट रूप से गारंटी देता है .keys()और .values()उनके तत्व उसी क्रम में हैं, जो ऊपर दिए गए दृष्टिकोण को काम करने की अनुमति देता है।)

वैकल्पिक रूप से:

inv_map = dict((my_map[k], k) for k in my_map)

या अजगर के 3.0 की व्यापक समझ का उपयोग करना

inv_map = {my_map[k] : k for k in my_map}

1
ध्यान दें कि यह केवल तभी काम करता है यदि कुंजियाँ अद्वितीय हैं (जो कि लगभग कभी भी ऐसा नहीं होता है यदि आप उन्हें उल्टा करना चाहते हैं)।
gented

Python.org/dev/peps/pep-0274 के अनुसार, 2.7+ में भी व्यापक समझ उपलब्ध है।
1

24

एक और, अधिक कार्यात्मक, तरीका:

my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))

3
पोस्ट करने का शुक्रिया। मुझे यकीन नहीं है कि यह पीईपी 279 में गुइडो वान रोसुम को उद्धृत करने के लिए बेहतर है: " filterऔर mapमर जाना चाहिए और सूची के बोध में शामिल होना चाहिए, अधिक संस्करण नहीं बढ़ना चाहिए"।
ब्रायन एम। हंट

2
हाँ, यह एक उचित बिंदु ब्रायन है। मैं इसे सिर्फ बातचीत के बिंदु के रूप में जोड़ रहा था। मैं समझ सकता हूँ के लिए सबसे बड़ा समझदार तरीका है। (और अधिक तेजी से मुझे लगता है कि संभावना है)
ब्रेंडन मैगुइरे

3
दूसरों की तुलना में कम पठनीय हो सकता है, लेकिन इस तरह dictसे अन्य मानचित्रण प्रकारों के साथ स्वैप करने में सक्षम होने का लाभ होता है जैसे कि collections.OrderedDictयाcollections.defaultdict
विल एस

10

यह रॉबर्ट द्वारा दिए गए उत्तर पर विस्तार करता है , जब आवेदन करने वाले के मान अद्वितीय नहीं होते हैं।

class ReversibleDict(dict):

    def reversed(self):
        """
        Return a reversed dict, with common values in the original dict
        grouped into a list in the returned dict.

        Example:
        >>> d = ReversibleDict({'a': 3, 'c': 2, 'b': 2, 'e': 3, 'd': 1, 'f': 2})
        >>> d.reversed()
        {1: ['d'], 2: ['c', 'b', 'f'], 3: ['a', 'e']}
        """

        revdict = {}
        for k, v in self.iteritems():
            revdict.setdefault(v, []).append(k)
        return revdict

कार्यान्वयन सीमित है कि आप reversedदो बार उपयोग नहीं कर सकते हैं और मूल वापस प्राप्त कर सकते हैं । यह सममित नहीं है। इसका परीक्षण पायथन 2.6 के साथ किया गया है। यहाँ का उपयोग मामला है कि मैं कैसे परिणामी हुक्म को प्रिंट करने के लिए उपयोग कर रहा हूं।

यदि आप इसके बजाय एक setसे अधिक का उपयोग करते हैं list, और अनियंत्रित अनुप्रयोग मौजूद हो सकते हैं जिसके लिए यह setdefault(v, []).append(k)उपयोग के बजाय समझ में आता है setdefault(v, set()).add(k)


यह भी सूचियों के बजाय सेट का उपयोग करने के लिए एक अच्छी जगह होगी, अर्थातrevdict.setdefault(v, set()).add(k)
mueslo

बेशक, लेकिन यह सटीक है कि इसका उपयोग करने का एक अच्छा कारण क्यों है set। यह आंतरिक प्रकार है जो यहां लागू होता है। क्या होगा यदि मैं सभी कुंजी ढूंढना चाहता हूं जहां मान नहीं हैं 1या नहीं 2? तब मैं बस d.keys() - inv_d[1] - inv_d[2](पायथन 3 में) कर सकता हूं
mueslo

9

हम डुप्लिकेट कुंजियों के साथ एक शब्दकोश को भी उल्टा कर सकते हैं defaultdict:

from collections import Counter, defaultdict

def invert_dict(d):
    d_inv = defaultdict(list)
    for k, v in d.items():
        d_inv[v].append(k)
    return d_inv

text = 'aaa bbb ccc ddd aaa bbb ccc aaa' 
c = Counter(text.split()) # Counter({'aaa': 3, 'bbb': 2, 'ccc': 2, 'ddd': 1})
dict(invert_dict(c)) # {1: ['ddd'], 2: ['bbb', 'ccc'], 3: ['aaa']}  

यहाँ देखें :

यह तकनीक उपयोग करने वाली समकक्ष तकनीक की तुलना में सरल और तेज है dict.setdefault()


6

उदाहरण के लिए, आपके पास निम्नलिखित शब्दकोष है:

dict = {'a': 'fire', 'b': 'ice', 'c': 'fire', 'd': 'water'}

और आप इसे ऐसे उल्टे रूप में प्राप्त करना चाहते हैं:

inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}

पहला उपाय । Inverting के लिए कुंजी-मान अपने शब्दकोश एक प्रयोग में जोड़े for-loop दृष्टिकोण:

# Use this code to invert dictionaries that have non-unique values

inverted_dict = dict()
for key, value in dict.items():
    inverted_dict.setdefault(value, list()).append(key)

दूसरा उपाय । उलटा के लिए एक शब्दकोश समझ दृष्टिकोण का उपयोग करें :

# Use this code to invert dictionaries that have unique values

inverted_dict = {value: key for key, value in dict.items()}

तीसरा उपायउलटा दृष्टिकोण का उपयोग करें (दूसरे समाधान पर निर्भर करता है):

# Use this code to invert dictionaries that have lists of values

dict = {value: key for key in inverted_dict for value in my_map[key]}

4
dictआरक्षित है और इसका प्रयोग चर नामों के लिए नहीं किया जाना चाहिए
crypdick

2
हमें बताना भूल गया कि क्या my_mapहै
crypdick

dictio()? क्या आपका मतलब था dict()?
जॉर्जी

5

सूची और शब्दकोश समझ का संयोजन। डुप्लिकेट कुंजियों को संभाल सकते हैं

{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}

1
जैसे stackoverflow.com/a/41861007/1709587 , यह एक O (n²) समस्या का हल है जो O (n) में कोड की अतिरिक्त लाइनों के एक जोड़े के साथ आसानी से हल हो जाता है।
मार्क एमी

2

यदि मूल्य अद्वितीय नहीं हैं, और आप थोड़े कट्टर हैं:

inv_map = dict(
    (v, [k for (k, xx) in filter(lambda (key, value): value == v, my_map.items())]) 
    for v in set(my_map.values())
)

विशेष रूप से एक बड़े हुक्म के लिए, ध्यान दें कि यह समाधान पायथन रिवर्स / मैपिंग को उल्टा करने की तुलना में बहुत कम कुशल है क्योंकि यह items()कई बार से अधिक लूप करता है।


7
यह सिर्फ सादा अपठनीय है और बनाए रखने योग्य कोड नहीं लिखने का एक अच्छा उदाहरण है। मैं नहीं करूंगा -1क्योंकि यह अभी भी सवाल का जवाब देता है, बस मेरी राय है।
रोस ब्रैडबरी

1

उपरोक्त अन्य कार्यों के अलावा, अगर आपको लंबोदर पसंद है:

invert = lambda mydict: {v:k for k, v in mydict.items()}

या, आप इसे इस तरह भी कर सकते हैं:

invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )

2
-1; आपके द्वारा किया गया सभी पृष्ठ से अन्य उत्तर ले लिया जाता है और उन्हें लंबोदर में डाल दिया जाता है। इसके अलावा, एक लैम्ब्डा को एक चर में असाइन करना पीईपी 8 का उल्लंघन है।
मार्क अमेरी

1

मुझे लगता है कि ऐसा करने का सबसे अच्छा तरीका एक वर्ग को परिभाषित करना है। यहाँ एक "सममित शब्दकोश" का कार्यान्वयन है:

class SymDict:
    def __init__(self):
        self.aToB = {}
        self.bToA = {}

    def assocAB(self, a, b):
        # Stores and returns a tuple (a,b) of overwritten bindings
        currB = None
        if a in self.aToB: currB = self.bToA[a]
        currA = None
        if b in self.bToA: currA = self.aToB[b]

        self.aToB[a] = b
        self.bToA[b] = a
        return (currA, currB)

    def lookupA(self, a):
        if a in self.aToB:
            return self.aToB[a]
        return None

    def lookupB(self, b):
        if b in self.bToA:
            return self.bToA[b]
        return None

जरूरत पड़ने पर विलोपन और पुनरावृति विधियां लागू करना काफी आसान है।

यह कार्यान्वयन एक संपूर्ण शब्दकोष (जो इस पृष्ठ पर सबसे लोकप्रिय समाधान लगता है) की तुलना में अधिक कुशल है। उल्लेख नहीं करने के लिए, आप जितना चाहें उतना अपने SymDict से मान जोड़ या हटा सकते हैं, और आपका उलटा-शब्दकोश हमेशा मान्य रहेगा - यदि आप केवल एक बार पूरे शब्दकोश को उलटते हैं तो यह सच नहीं है।


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

@ ब्रायन। हंट यह याददाश्त को बंद करता है, लेकिन बहुत कुछ नहीं। आप केवल प्रत्येक ऑब्जेक्ट को दो सेट पॉइंटर्स स्टोर करते हैं। यदि आपकी वस्तुएँ एकल पूर्णांक से बहुत बड़ी हैं, तो इससे बहुत अंतर नहीं पड़ेगा। यदि आपके पास दूसरी तरफ छोटी-छोटी वस्तुओं की विशाल तालिका है, तो आपको उन सुझावों पर विचार करने की आवश्यकता हो सकती है ...
NcAdams

और मैं मानता हूं, यहां और भी बहुत कुछ किया जाना है - मैं इसे पूरी तरह से काम करने के तरीके में बदल सकता हूं
NcAdams

2
"यह कार्यान्वयन एक संपूर्ण शब्दकोष बनाने की तुलना में अधिक कुशल है" - उम, क्यों? मुझे कोई प्रशंसनीय तरीका नहीं दिख रहा है इस दृष्टिकोण से महत्वपूर्ण प्रदर्शन लाभ हो सकता है; आप अभी भी इस तरह से दो शब्दकोश प्राप्त कर चुके हैं। अगर कुछ भी हो, तो मैं उम्मीद करता हूं कि यह समझने की तुलना में धीमा होगा, कहना होगा, यदि आप एक व्यापक समझ के साथ इन्वर्टर को उल्टा करते हैं, तो आप अंतर्निहित पायथॉन को पूर्व में पता कर सकते हैं कि अंतर्निहित सी डेटा संरचना में कितने बाल्टी आवंटित करने और उलटा नक्शा बनाने के लिए बिना बुलाए कभी भी dictresize, लेकिन यह दृष्टिकोण इस संभावना से इनकार करता है कि पायथन।
मार्क अमेरी

1

यह गैर-अद्वितीय मानों को संभालता है और अद्वितीय मामले के लुक को बनाए रखता है।

inv_map = {v:[k for k in my_map if my_map[k] == v] for v in my_map.itervalues()}

पायथन 3.x के लिए, के itervaluesसाथ बदलें values


3
यह समाधान एक लाइनर के रूप में काफी सुरुचिपूर्ण है और यह गैर अद्वितीय मूल्यों के मामले का प्रबंधन करता है। हालाँकि, यह O (n2) में एक जटिलता है, जिसका अर्थ है कि यह कई दर्जनों तत्वों के लिए ठीक होना चाहिए, लेकिन यदि आप अपने प्रारंभिक शब्दकोश में कई सैकड़ों हजारों तत्व रखते हैं, तो यह व्यावहारिक उपयोग के लिए बहुत धीमा होगा। डिफ़ॉल्ट डिक्टेड पर आधारित समाधान इस तरह से तेजी से होते हैं।
गाबुजो

गबुजो काफी सही है। यह संस्करण (यकीनन) कुछ की तुलना में स्पष्ट है, लेकिन यह बड़े डेटा के लिए उपयुक्त नहीं है।
Ersatz Kwisatz

0

प्रकार सूची के मूल्यों के लिए फ़ंक्शन सममित है; उलट-पुलट (रिवर्स_डिक्ट (डिक्शनरी)) करते समय ट्यूपल्स को सूचियों में शामिल किया जाता है

def reverse_dict(dictionary):
    reverse_dict = {}
    for key, value in dictionary.iteritems():
        if not isinstance(value, (list, tuple)):
            value = [value]
        for val in value:
            reverse_dict[val] = reverse_dict.get(val, [])
            reverse_dict[val].append(key)
    for key, value in reverse_dict.iteritems():
        if len(value) == 1:
            reverse_dict[key] = value[0]
    return reverse_dict

0

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

def r_maping(dictionary):
    List_z=[]
    Map= {}
    for z, x in dictionary.iteritems(): #iterate through the keys and values
        Map.setdefault(x,List_z).append(z) #Setdefault is the same as dict[key]=default."The method returns the key value available in the dictionary and if given key is not available then it will return provided default value. Afterward, we will append into the default list our new values for the specific key.
    return Map

0

गैर-विशेषण मानचित्रों के लिए तेजी से कार्यात्मक समाधान (मूल्य अद्वितीय नहीं):

from itertools import imap, groupby

def fst(s):
    return s[0]

def snd(s):
    return s[1]

def inverseDict(d):
    """
    input d: a -> b
    output : b -> set(a)
    """
    return {
        v : set(imap(fst, kv_iter))
        for (v, kv_iter) in groupby(
            sorted(d.iteritems(),
                   key=snd),
            key=snd
        )
    }

सिद्धांत रूप में यह सेट में जोड़ने (या सूची में जोड़कर) की तुलना में तेज होना चाहिए, एक-एक करके अनिवार्य समाधान में

दुर्भाग्य से मूल्यों को क्रमबद्ध करना पड़ता है, समूहन द्वारा छंटाई की आवश्यकता होती है।


1
"सिद्धांत रूप में यह सेट में जोड़ने से तेज होना चाहिए (या सूची में जोड़कर) एक-एक करके" - नहीं। nमूल तानाशाही में तत्वों को देखते हुए , आपके दृष्टिकोण में O(n log n)तानाशाह की वस्तुओं को छांटने की आवश्यकता के कारण समय की जटिलता होती है, जबकि अनुभवहीन अनिवार्य दृष्टिकोण में O(n)समय की जटिलता होती है। सभी के लिए मैं अपने दृष्टिकोण तेजी से जब तक बड़ी मूर्खता हो सकता है पता है dictमें अभ्यास है, लेकिन यह निश्चित रूप से सिद्धांत रूप में नहीं तेज है।
मार्क अमेरी

0

अजगर 2.7 / 3.x के लिए यह प्रयास करें

inv_map={};
for i in my_map:
    inv_map[my_map[i]]=i    
print inv_map

-1

मैं इसे अजगर 2 में इस तरह से करूंगा।

inv_map = {my_map[x] : x for x in my_map}

कुंजी-वैल्यू जोड़े को एक साथ dict.items(या iteritemsपायथन 2 में) अलग-अलग करना, कुंजियों की पुनरावृति करते समय प्रत्येक मूल्य को अलग-अलग निकालने से अधिक कुशल है।
JPP

-1
def invertDictionary(d):
    myDict = {}
  for i in d:
     value = d.get(i)
     myDict.setdefault(value,[]).append(i)   
 return myDict
 print invertDictionary({'a':1, 'b':2, 'c':3 , 'd' : 1})

यह आउटपुट प्रदान करेगा: {1: ['a', 'd'], 2: ['b'], 3: ['c']}


कुंजी-वैल्यू जोड़े को एक साथ dict.items(या iteritemsपायथन 2 में) अलग-अलग करना, कुंजियों की पुनरावृति करते समय प्रत्येक मूल्य को अलग-अलग निकालने से अधिक कुशल है। साथ ही, आपने एक उत्तर में कोई स्पष्टीकरण नहीं जोड़ा है जो दूसरों को डुप्लिकेट करता है।
जेपी

-1
  def reverse_dictionary(input_dict):
      out = {}
      for v in input_dict.values():  
          for value in v:
              if value not in out:
                  out[value.lower()] = []

      for i in input_dict:
          for j in out:
              if j in map (lambda x : x.lower(),input_dict[i]):
                  out[j].append(i.lower())
                  out[j].sort()
      return out

यह कोड इस प्रकार है:

r = reverse_dictionary({'Accurate': ['exact', 'precise'], 'exact': ['precise'], 'astute': ['Smart', 'clever'], 'smart': ['clever', 'bright', 'talented']})

print(r)

{'precise': ['accurate', 'exact'], 'clever': ['astute', 'smart'], 'talented': ['smart'], 'bright': ['smart'], 'exact': ['accurate'], 'smart': ['astute']}

1
आम तौर पर, उत्तर बहुत अधिक सहायक होते हैं यदि वे एक स्पष्टीकरण शामिल करते हैं कि कोड क्या करने का इरादा है, और क्यों वह दूसरों को पेश किए बिना समस्या को हल करता है।
टॉम अरंडा

1
यह बहुत अच्छा है, लेकिन बहुत सारे अस्पष्ट निर्णय (उदाहरण के लिए, चाबियों के मामले में कम क्यों?)
ल्यूडविकस अकेलिस

-2

नहीं पूरी तरह से अलग कुछ, बस रसोई की किताब से एक बिट फिर से लिखा नुस्खा। setdefaultप्रत्येक समय के बजाय इसे प्राप्त करने की विधि द्वारा इसे बनाए रखने के द्वारा अनुकूलित किया गया है , यह futhermore है :

def inverse(mapping):
    '''
    A function to inverse mapping, collecting keys with simillar values
    in list. Careful to retain original type and to be fast.
    >> d = dict(a=1, b=2, c=1, d=3, e=2, f=1, g=5, h=2)
    >> inverse(d)
    {1: ['f', 'c', 'a'], 2: ['h', 'b', 'e'], 3: ['d'], 5: ['g']}
    '''
    res = {}
    setdef = res.setdefault
    for key, value in mapping.items():
        setdef(value, []).append(key)
    return res if mapping.__class__==dict else mapping.__class__(res)

सीपीएक्स 3.x के तहत चलाने के लिए डिज़ाइन किया गया, 2.x के mapping.items()साथ बदलेंmapping.iteritems()

मेरी मशीन पर अन्य उदाहरणों की तुलना में थोड़ा तेज चलता है


1
एक परिणाम के रूप में निर्माण करना dictऔर फिर अंत में वांछित वर्ग में परिवर्तित करना (सही प्रकार की कक्षा के साथ शुरू करने के बजाय) मुझे ऐसा लग रहा है जैसे यह पूरी तरह से परिहार्य प्रदर्शन हिट है।
मार्क अमेरी

-2

मैंने इसे 'for' और Method '.get ()' की मदद से लिखा था और मैंने डिक्शनरी के 'मैप' का नाम बदलकर 'मैप 1' कर दिया क्योंकि 'मैप' एक फंक्शन है।

def dict_invert(map1):
    inv_map = {} # new dictionary
    for key in map1.keys():
        inv_map[map1.get(key)] = key
    return inv_map

-2

यदि मूल्य अद्वितीय नहीं हैं और एक हैश (एक आयाम) हो सकता है:

for k, v in myDict.items():
    if len(v) > 1:
        for item in v:
            invDict[item] = invDict.get(item, [])
            invDict[item].append(k)
    else:
        invDict[v] = invDict.get(v, [])
        invDict[v].append(k)

और एक पुनरावृत्ति के साथ यदि आपको गहरी खुदाई करने की आवश्यकता है तो बस एक आयाम:

def digList(lst):
    temp = []
    for item in lst:
        if type(item) is list:
            temp.append(digList(item))
        else:
            temp.append(item)
    return set(temp)

for k, v in myDict.items():
    if type(v) is list:
        items = digList(v)
        for item in items:
            invDict[item] = invDict.get(item, [])
            invDict[item].append(k)
    else:
        invDict[v] = invDict.get(v, [])
        invDict[v].append(k)

आप एक defaultdict का उपयोग कर अपने समाधान में सुधार हो सकता है: यह सब invDict [आइटम] = invDict.get (आइटम, []) लाइनों से हटा देंगे
gabuzo

यहां आपका पहला दृष्टिकोण एक अपवाद को बढ़ाता {"foo": "bar"}है {'b': ['foo'], 'a': ['foo'], 'r': ['foo']}और अगर कोई मूल्य इसमें शामिल myDictनहीं है, तो यह एक अपवाद नहीं है। मुझे यकीन नहीं है कि आप यहां किस व्यवहार को लागू करने की कोशिश कर रहे थे, लेकिन जो आपने वास्तव में लागू किया है वह कुछ बहुत ज्यादा है जो कोई भी नहीं चाहता है।
मार्क एमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.