এর মতো একটি অভিধান দেওয়া হয়েছে:
my_map = {'a': 1, 'b': 2}
কেউ কীভাবে এই মানচিত্রটি উল্টাতে পারে:
inv_map = {1: 'a', 2: 'b'}
এর মতো একটি অভিধান দেওয়া হয়েছে:
my_map = {'a': 1, 'b': 2}
কেউ কীভাবে এই মানচিত্রটি উল্টাতে পারে:
inv_map = {1: 'a', 2: 'b'}
উত্তর:
পাইথন ২.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()}
The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon
। Dict
এটি সেইভাবেই থাকবে এমন কোনও গ্যারান্টি নেই তাই একই আচরণের উপর নির্ভর করে কোডটি লিখবেন না OrderedDict
।
অনুমান করে যে ডিকের মানগুলি অনন্য:
dict((v, k) for k, v in my_map.iteritems())
iteritems()
আউটপুট আসার সম্ভাব্য কোনও গ্যারান্টি নেই , সুতরাং এটি ধরে নেওয়া যেতে পারে যে একটি স্বেচ্ছাসেবক কী কোনও অনন্য-মানের জন্য নির্ধারিত হবে, এমন একটি উপায়ে যা কিছু শর্তে স্পষ্টতই পুনরুত্পাদনযোগ্য হবে, তবে সাধারণভাবে তা হয় না।
iteritems()
পদ্ধতি নেই এবং এই পদ্ধতির কাজ হবে না; items()
পরিবর্তে গ্রহণযোগ্য উত্তরে প্রদর্শিত হিসাবে সেখানে ব্যবহার করুন । এছাড়াও, একটি অভিধান বোঝার আহ্বান কল করার চেয়ে এই সুন্দর করে তুলবে dict
।
মানগুলি যদি my_map
অনন্য না হয়:
inv_map = {}
for k, v in my_map.iteritems():
inv_map[v] = inv_map.get(v, [])
inv_map[v].append(k)
inv_map.get(v, [])
ইতিমধ্যে যুক্ত তালিকাটি যদি থাকে তবে তা ফেরত দেয়, সুতরাং অ্যাসাইনমেন্টটি খালি তালিকায় পুনরায় সেট হয় না। setdefault
এখনও সুন্দর হতে হবে, যদিও।
inv_map.setdefault(v, set()).add(k)
।
my_map.items()
পরিবর্তে ব্যবহার করুন my_map.iteritems()
।
আপনার ম্যাপিংয়ের ধরণটি সংরক্ষণ করার সময় এটি করার জন্য (ধরে নেওয়া এটি একটি dict
বা dict
সাবক্লাস):
def inverse_mapping(f):
return f.__class__(map(reversed, f.items()))
এটা চেষ্টা কর:
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}
আরেকটি, আরও কার্যকর, উপায়:
my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))
filter
এবং map
মরে যাওয়া উচিত এবং তালিকা অনুধাবনীতে ডুবে যাওয়া উচিত, আরও বৈকল্পিক বৃদ্ধি করা উচিত নয়"।
dict
অন্য ম্যাপিংয়ের মতো যেমনcollections.OrderedDict
collections.defaultdict
এটি রবার্টের উত্তরের উপর প্রসারিত হয় , যখন ডিকের মানগুলি অনন্য নয় তখন প্রয়োগ করে।
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
দুবার ব্যবহার করতে পারবেন না এবং আসল ফিরে পাবেন। এটি এর মতো প্রতিসম নয়। এটি পাইথন ২.6 দিয়ে পরীক্ষা করা হয়। আমি কীভাবে ফলাফল ডিকটি মুদ্রণের জন্য ব্যবহার করছি তার একটি ব্যবহারের কেস এখানে ।
আপনি যদি এটির পরিবর্তে একটির set
চেয়ে একটি ব্যবহার করতে চান list
, এবং এমন কোনও আনর্ডারড অ্যাপ্লিকেশন থাকতে পারে যার জন্য এটি setdefault(v, []).append(k)
ব্যবহারের পরিবর্তে এটি বোঝা যায় setdefault(v, set()).add(k)
।
revdict.setdefault(v, set()).add(k)
set
। এটি এখানে প্রযোজ্য অভ্যন্তরীণ ধরণ। আমি যদি সমস্ত কীগুলি খুঁজে পেতে চাই যেখানে মানগুলি হয় না 1
বা হয় না 2
? তারপরে আমি কেবল d.keys() - inv_d[1] - inv_d[2]
(পাইথন 3 এ) করতে পারি
আমরা নকল কী ব্যবহার করে একটি অভিধানও বিপরীত করতে পারি 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()
।
উদাহরণস্বরূপ, আপনার কাছে নিম্নলিখিত অভিধান রয়েছে:
dict = {'a': 'fire', 'b': 'ice', 'c': 'fire', 'd': 'water'}
এবং আপনি এটি একটি উল্টানো আকারে পেতে চান:
inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}
প্রথম সমাধান । ইনভার্টারিং জন্য কী-মান আপনার অভিধান একটি ব্যবহারে জোড়া 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]}
dict
সংরক্ষিত এবং পরিবর্তনশীল নামের জন্য ব্যবহার করা উচিত নয়
my_map
হয়
dictio()
? মানে dict()
?
তালিকা এবং অভিধান বোঝার সংমিশ্রণ। সদৃশ কী পরিচালনা করতে পারে
{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}
মানগুলি যদি অনন্য না হয় এবং আপনি কিছুটা কঠোর হন:
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()
একাধিকবার লুপ করে ।
-1
কারণ এটি এখনও প্রশ্নের উত্তর দেয়, কেবল আমার মতামত।
উপরে বর্ণিত অন্যান্য ফাংশনগুলি ছাড়াও, যদি আপনি ল্যাম্বডাস পছন্দ করেন:
invert = lambda mydict: {v:k for k, v in mydict.items()}
অথবা, আপনি এটিও এইভাবে করতে পারেন:
invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )
আমি মনে করি এটি করার সর্বোত্তম উপায়টি কোনও শ্রেণির সংজ্ঞা দেওয়া। এখানে একটি "প্রতিসাম্য অভিধান" প্রয়োগ করা হচ্ছে:
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
মুছে ফেলা এবং পুনরাবৃত্তি পদ্ধতিগুলির প্রয়োজন হলে প্রয়োগ করা যথেষ্ট সহজ।
এই বাস্তবায়নটি পুরো অভিধানটি উল্টানোর চেয়ে আরও কার্যকর (যা এই পৃষ্ঠার সর্বাধিক জনপ্রিয় সমাধান বলে মনে হয়) than উল্লেখ করার মতো নয়, আপনি আপনার সিমডিক্ট থেকে যতটা চান মানগুলি যুক্ত করতে বা মুছতে পারেন, এবং আপনার বিপরীত অভিধান সর্বদা কার্যকর থাকবে - আপনি যদি পুরো অভিধানটি একবারে উল্টে করেন তবে এটি সত্য নয়।
dictresize
, কিন্তু এই পদ্ধতির পাইথন সেই সম্ভাবনাটিকে অস্বীকার করে।
এটি অ-অনন্য মূল্যবোধ পরিচালনা করে এবং অনন্য কেসের চেহারা অনেকটাই ধরে রাখে।
inv_map = {v:[k for k in my_map if my_map[k] == v] for v in my_map.itervalues()}
পাইথন ৩.x এর itervalues
সাথে প্রতিস্থাপন করুন values
।
টাইপ তালিকার মানগুলির জন্য কার্যকারিতাটি প্রতিসম হয়; রিভার্স_ডিক্ট (রিভার্স_ডিক্ট (অভিধান)) সম্পাদন করার সময় টিপলগুলি তালিকায় toাকা থাকে
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
যেহেতু অভিধানগুলিতে মানগুলির তুলনায় অভিধানের মধ্যে একটি অনন্য কী প্রয়োজন, তাই আমাদের নতুন নির্দিষ্ট কীগুলির মধ্যে অন্তর্ভুক্ত করার জন্য বিপরীত মানগুলিকে সাজানোর তালিকায় যুক্ত করতে হবে।
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
অ বাইজিক মানচিত্রের জন্য দ্রুত কার্যকরী সমাধান (মানগুলি অনন্য নয়):
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
)
}
তাত্ত্বিকভাবে এটি আবশ্যক সমাধানের মতো একের পর এক সেট (বা তালিকায় সংযোজন) যুক্ত করার চেয়ে দ্রুত হওয়া উচিত ।
দুর্ভাগ্যক্রমে মানগুলি বাছাইযোগ্য হতে হবে, গোষ্ঠীভুক্ত দ্বারা বাছাই করা প্রয়োজন।
n
আসল ডিকের উপাদানগুলি দেওয়া , O(n log n)
ডিকের আইটেমগুলি বাছাই করার প্রয়োজনীয়তার কারণে আপনার পদ্ধতির সময় জটিলতা রয়েছে , যেখানে নিষ্পাপ আবশ্যক পদ্ধতির O(n)
সময় জটিলতা রয়েছে। সব জন্য আমি তোমার পদ্ধতির দ্রুত পর্যন্ত অদ্ভূত বড় হতে পারে জানি dict
মধ্যে গুলি অনুশীলন , কিন্তু এটা অবশ্যই তত্ত্ব নেই দ্রুততর।
আমি অজগর 2 এ সেভাবে করব।
inv_map = {my_map[x] : x for x in my_map}
dict.items
(বা iteritems
পাইথন 2 এ) মাধ্যমে কীগুলি পুনরাবৃত্তি করার সময় প্রতিটি মান পৃথক করে তোলার চেয়ে আরও কার্যকর।
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: ['বি'], 3: ['গ']}
dict.items
(বা iteritems
পাইথন 2 এ) মাধ্যমে কীগুলি পুনরাবৃত্তি করার সময় প্রতিটি মান পৃথকভাবে আহরণের চেয়ে আরও কার্যকর। এছাড়াও, আপনি এমন উত্তরের কোনও ব্যাখ্যা যোগ করেন নি যা অন্যকে সদৃশ করে।
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']}
পুরোপুরি আলাদা কিছু নয়, কুকবুক থেকে কিছুটা পুনরায় লেখা রেসিপি। এটি setdefault
প্রতিবার ইনস্ট্যান্সের মাধ্যমে পাওয়ার পরিবর্তে রক্ষণাবেক্ষণ পদ্ধতি দ্বারা আরও অনুকূল করা হয়েছে :
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 এর অধীনে চালিত হওয়ার জন্য ডিজাইন করা হয়েছে, এর mapping.items()
সাথে 2.x প্রতিস্থাপন করুনmapping.iteritems()
আমার মেশিনে এখানে অন্যান্য উদাহরণগুলির চেয়ে কিছুটা দ্রুত চলে
dict
এবং তারপরে শেষে কাঙ্ক্ষিত শ্রেণিতে রূপান্তর করা (সঠিক ধরণের শ্রেণীর সাথে শুরু করার চেয়ে) আমার কাছে মনে হয় এটি সম্পূর্ণরূপে এড়ানো যায় এমন পারফরম্যান্স হিট করে, যেমন এখানে।
আমি চক্র 'for' এবং পদ্ধতি '.get ()' এর সাহায্যে এটি লিখেছিলাম এবং অভিধানের 'মানচিত্র' নামটি পরিবর্তিত করে 'মানচিত্র 1' করে রেখেছি কারণ 'মানচিত্র' একটি ফাংশন।
def dict_invert(map1):
inv_map = {} # new dictionary
for key in map1.keys():
inv_map[map1.get(key)] = key
return inv_map
মানগুলি যদি অনন্য না হয় এবং হ্যাশ (এক মাত্রা) হতে পারে:
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)
{"foo": "bar"}
হয় {'b': ['foo'], 'a': ['foo'], 'r': ['foo']}
এবং কোনও মান যদি myDict
পুনরাবৃত্ত না হয় তবে একটি ব্যতিক্রম উত্থাপন করে । আপনি এখানে কোন আচরণ বাস্তবায়নের চেষ্টা করছেন তা আমি নিশ্চিত নই, তবে আপনি যা বাস্তবায়িত করেছেন তা হ'ল কেউ চাইবে না।
my_map.items()
পাশাপাশি কাজ করে