互换词典
Interchangeable dictionary
我希望有一个可互换的字典,即值与键映射,键与值映射,这样如果我们知道一个元素,就可以知道另一个伙伴。在 python dict 中,使用键,我们可以获得值,但反之亦然。我怎样才能做到这一点?
注意:为了可互换性,key: value & value: key 之间必须存在 1-1 映射。
示例:
key = {'a':'1','b':'2','c':'3'}
So, I should be able to get 1 for key['a'] & 'a' for key['1']
一种可能的方法是...您可以简单地更新现有字典,因为它包含所有相反的 key-value 对,如下所示:
dict1 = {'a': '1','b' :'2','c': '3'}
dict2 = dict(zip(dict1.values(), dict1.keys())) # create value-key pair dictionary
dict1.update(dict2) # combining dict2 with dict1
print(dict1)
#{'a': '1', 'b': '2', 'c': '3', '1': 'a', '2': 'b', '3': 'c'}
但是,您应该小心使用它,因为可能存在重复的键和值。
假设永远不会发生碰撞(即键和值是不相交的集合),那么您可以创建“镜像”dict
,然后按如下方式利用 collections.ChainMap
import collections
key = {'a':'1','b':'2','c':'3'}
rev_key = dict(i[::-1] for i in key.items())
final = collections.ChainMap(key,rev_key)
print(final['a'])
print(final['3'])
print(final['c'])
输出
1
c
3
警告:此解决方案假定您只想使用 final
进行阅读。它不支持反映您插入的值(例如 final['d'] = '4'
不会导致 final['4']
变为 'd'
)
这是一个示例,说明您可以如何创建一个 class 来为您执行此操作。请注意,这在设置新值/编辑现有值时非常慢。
class DoubleDict:
def __init__(self, *dicts, **extras):
self.dict1 = {}
for dct in dicts:
self.dict1 |= dct
self.dict1 |= extras
self.dict2 = dict(zip(self.dict1.values(), self.dict1.keys()))
def __getitem__(self, key):
try: return self.dict1.__getitem__(key)
except KeyError: return self.dict2.__getitem__(key)
def __setitem__(self, key, value):
if key in self.dict1:
self.dict2.pop(self.dict1[key])
self.dict1.pop(key)
elif key in self.dict2:
self.dict1.pop(self.dict2[key])
self.dict2.pop(key)
if value in self.dict1:
self.dict2.pop(self.dict1[value])
self.dict1.pop(value)
elif value in self.dict2:
self.dict1.pop(self.dict2[value])
self.dict2.pop(value)
self.dict1[key] = value
self.dict2[value] = key
def __iter__(self):
total_dict = self.dict1 | self.dict2
return total_dict.__iter__()
def __repr__(self):
return f"DoubleDict({repr(self.dict1)})"
def __str__(self):
return "\n".join(f"{key} <==> {self.dict1[key]}" for key in self.dict1)
工作原理如下:
a = DoubleDict({1: 2, 3: 4, 5: 6, 7: 8})
print(a)
# 1 <==> 2
# 3 <==> 4
# 5 <==> 6
# 7 <==> 8
a[1] = 3
# Now the 3,4 pair and the 1,2 pair no longer exist, but there is a new 3,1 pair
print(a[1], a[3])
# 3 1
print(a)
# 5 <==> 6
# 7 <==> 8
# 1 <==> 3
我希望有一个可互换的字典,即值与键映射,键与值映射,这样如果我们知道一个元素,就可以知道另一个伙伴。在 python dict 中,使用键,我们可以获得值,但反之亦然。我怎样才能做到这一点? 注意:为了可互换性,key: value & value: key 之间必须存在 1-1 映射。
示例:
key = {'a':'1','b':'2','c':'3'}
So, I should be able to get 1 for key['a'] & 'a' for key['1']
一种可能的方法是...您可以简单地更新现有字典,因为它包含所有相反的 key-value 对,如下所示:
dict1 = {'a': '1','b' :'2','c': '3'}
dict2 = dict(zip(dict1.values(), dict1.keys())) # create value-key pair dictionary
dict1.update(dict2) # combining dict2 with dict1
print(dict1)
#{'a': '1', 'b': '2', 'c': '3', '1': 'a', '2': 'b', '3': 'c'}
但是,您应该小心使用它,因为可能存在重复的键和值。
假设永远不会发生碰撞(即键和值是不相交的集合),那么您可以创建“镜像”dict
,然后按如下方式利用 collections.ChainMap
import collections
key = {'a':'1','b':'2','c':'3'}
rev_key = dict(i[::-1] for i in key.items())
final = collections.ChainMap(key,rev_key)
print(final['a'])
print(final['3'])
print(final['c'])
输出
1
c
3
警告:此解决方案假定您只想使用 final
进行阅读。它不支持反映您插入的值(例如 final['d'] = '4'
不会导致 final['4']
变为 'd'
)
这是一个示例,说明您可以如何创建一个 class 来为您执行此操作。请注意,这在设置新值/编辑现有值时非常慢。
class DoubleDict:
def __init__(self, *dicts, **extras):
self.dict1 = {}
for dct in dicts:
self.dict1 |= dct
self.dict1 |= extras
self.dict2 = dict(zip(self.dict1.values(), self.dict1.keys()))
def __getitem__(self, key):
try: return self.dict1.__getitem__(key)
except KeyError: return self.dict2.__getitem__(key)
def __setitem__(self, key, value):
if key in self.dict1:
self.dict2.pop(self.dict1[key])
self.dict1.pop(key)
elif key in self.dict2:
self.dict1.pop(self.dict2[key])
self.dict2.pop(key)
if value in self.dict1:
self.dict2.pop(self.dict1[value])
self.dict1.pop(value)
elif value in self.dict2:
self.dict1.pop(self.dict2[value])
self.dict2.pop(value)
self.dict1[key] = value
self.dict2[value] = key
def __iter__(self):
total_dict = self.dict1 | self.dict2
return total_dict.__iter__()
def __repr__(self):
return f"DoubleDict({repr(self.dict1)})"
def __str__(self):
return "\n".join(f"{key} <==> {self.dict1[key]}" for key in self.dict1)
工作原理如下:
a = DoubleDict({1: 2, 3: 4, 5: 6, 7: 8})
print(a)
# 1 <==> 2
# 3 <==> 4
# 5 <==> 6
# 7 <==> 8
a[1] = 3
# Now the 3,4 pair and the 1,2 pair no longer exist, but there is a new 3,1 pair
print(a[1], a[3])
# 3 1
print(a)
# 5 <==> 6
# 7 <==> 8
# 1 <==> 3