在python中使用dict值获取dict键
我的问题是:如何使用字典值获取字典键在python中使用dict值获取dict键,python,dictionary,key,Python,Dictionary,Key,我的问题是:如何使用字典值获取字典键 d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}} 我想把2的钥匙换成2的钥匙 谢谢。我不知道最好的解决方案是什么,但有一种可能是将字典反转,使值变成键,然后只进行正常的键查找。这将反转字典: forward_dict = { 'key1': 'val1', 'key2': 'val2'} reverse_dict = dict([(v,k) for k,v in forw
d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}}
我想把2的钥匙换成2的钥匙
谢谢。我不知道最好的解决方案是什么,但有一种可能是将字典反转,使值变成键,然后只进行正常的键查找。这将反转字典:
forward_dict = { 'key1': 'val1', 'key2': 'val2'}
reverse_dict = dict([(v,k) for k,v in forward_dict.items()])
鉴于val1,我可以:
reverse_dict["val1"]
找到相应的键。此解决方案存在明显的问题-例如,如果您的值不是唯一的,您将丢失一些信息。我不知道最佳解决方案是什么,但有一种可能是将字典反转,使值成为键,然后只执行普通的键查找。这将反转字典:
forward_dict = { 'key1': 'val1', 'key2': 'val2'}
reverse_dict = dict([(v,k) for k,v in forward_dict.items()])
鉴于val1,我可以:
reverse_dict["val1"]
找到相应的键。此解决方案存在明显的问题-例如,如果您的值不唯一,您将丢失一些信息。编写代码以反转字典,即创建一个新字典,将旧字典的值映射到旧字典的键。
由于您似乎正在处理嵌套字典,这显然会更棘手。找出解决问题所需的最低限度,并编写相应的代码,即,如果您的问题只处理dicts中的dicts,而dicts中又没有任何dicts,则不要创建一个能够工作任意嵌套深度的解决方案。编写代码以反转字典,即创建一个新字典,将旧字典的值映射到键旧的那个。
由于您似乎正在处理嵌套字典,这显然会更棘手。找出解决问题所需的最低限度并编写代码,即如果您的问题只处理dicts中的dicts,而dicts中又没有任何dicts,则不要创建一个可以工作任意嵌套深度的解决方案如果您不想反转字典,这里有另一个可能的解决方案:
def get_key_from_value(my_dict, v):
for key,value in my_dict.items():
if value == v:
return key
return None
>>> d = {1: 'one', 2: 'two'}
>>> get_key_from_value(d,'two')
2
如果您不想撤销字典,以下是另一种可能的解决方案:
def get_key_from_value(my_dict, v):
for key,value in my_dict.items():
if value == v:
return key
return None
>>> d = {1: 'one', 2: 'two'}
>>> get_key_from_value(d,'two')
2
以下内容将为两级示例创建反向词典:
d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}}
r = {}
for d1 in d:
for d2 in d[d1]:
r[d[d1][d2]] = d1
结果是:
>>> r
{'four': 'dict1', 'three': 'dict1', 'two': 'dict2', 'one': 'dict2'}
以下内容将为两级示例创建反向词典:
d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}}
r = {}
for d1 in d:
for d2 in d[d1]:
r[d[d1][d2]] = d1
结果是:
>>> r
{'four': 'dict1', 'three': 'dict1', 'two': 'dict2', 'one': 'dict2'}
下面是一个可以处理任意嵌套字典的递归解决方案:
>>> import collections
>>> def dict_find_recursive(d, target):
... if not isinstance(d, collections.Mapping):
... return d == target
... else:
... for k in d:
... if dict_find_recursive(d[k], target) != False:
... return k
... return False
从长远来看,它不如反向词典那么有效,但如果你不经常进行这种反向搜索,这可能没什么关系。请注意,您必须显式地将dict_find_recursived[k]的结果、target与False进行比较,否则像这样的伪键会导致搜索失败。事实上,如果使用False作为密钥,即使这个版本也会失败;一个完全通用的解决方案将使用一个独特的哨兵对象来表示错误
一些用法示例:
>>> d = {'dict1': {3: 'three', 4: 'four'}, 'dict2': {1: 'one', 2: 'two'}}
>>> dict_find_recursive(d, 'two')
'dict2'
>>> dict_find_recursive(d, 'five')
False
>>> d = {'dict1': {3: 'three', 4: 'four'}, 'dict2': {1: 'one', 2: 'two'},
'dict3': {1: {1:'five'}, 2: 'six'}}
>>> dict_find_recursive(d, 'five')
'dict3'
>>> dict_find_recursive(d, 'six')
'dict3'
如果要反转任意嵌套的词典集,递归生成器是您的朋友:
>>> def dict_flatten(d):
... if not isinstance(d, collections.Mapping):
... yield d
... else:
... for value in d:
... for item in dict_flatten(d[value]):
... yield item
...
>>> list(dict_flatten(d))
['three', 'four', 'five', 'six', 'one', 'two']
上面只是列出了字典中所有不是映射的值。然后,您可以将这些值中的每一个映射到一个键,如下所示:
>>> def reverse_nested_dict(d):
... for k in d:
... if not isinstance(d[k], collections.Mapping):
... yield (d[k], k)
... else:
... for item in dict_flatten(d[k]):
... yield (item, k)
...
这将生成一组元组,因此不会丢失任何信息:
>>> for tup in reverse_nested_dict(d):
... print tup
...
('three', 'dict1')
('four', 'dict1')
('five', 'dict3')
('six', 'dict3')
('one', 'dict2')
('two', 'dict2')
如果您知道所有非映射值都是可散列的,并且知道它们是唯一的,或者您不关心冲突,那么只需将结果元组传递给dict:
下面是一个可以处理任意嵌套字典的递归解决方案:
>>> import collections
>>> def dict_find_recursive(d, target):
... if not isinstance(d, collections.Mapping):
... return d == target
... else:
... for k in d:
... if dict_find_recursive(d[k], target) != False:
... return k
... return False
从长远来看,它不如反向词典那么有效,但如果你不经常进行这种反向搜索,这可能没什么关系。请注意,您必须显式地将dict_find_recursived[k]的结果、target与False进行比较,否则像这样的伪键会导致搜索失败。事实上,如果使用False作为密钥,即使这个版本也会失败;一个完全通用的解决方案将使用一个独特的哨兵对象来表示错误
一些用法示例:
>>> d = {'dict1': {3: 'three', 4: 'four'}, 'dict2': {1: 'one', 2: 'two'}}
>>> dict_find_recursive(d, 'two')
'dict2'
>>> dict_find_recursive(d, 'five')
False
>>> d = {'dict1': {3: 'three', 4: 'four'}, 'dict2': {1: 'one', 2: 'two'},
'dict3': {1: {1:'five'}, 2: 'six'}}
>>> dict_find_recursive(d, 'five')
'dict3'
>>> dict_find_recursive(d, 'six')
'dict3'
如果要反转任意嵌套的词典集,递归生成器是您的朋友:
>>> def dict_flatten(d):
... if not isinstance(d, collections.Mapping):
... yield d
... else:
... for value in d:
... for item in dict_flatten(d[value]):
... yield item
...
>>> list(dict_flatten(d))
['three', 'four', 'five', 'six', 'one', 'two']
上面只是列出了字典中所有不是映射的值。然后,您可以将这些值中的每一个映射到一个键,如下所示:
>>> def reverse_nested_dict(d):
... for k in d:
... if not isinstance(d[k], collections.Mapping):
... yield (d[k], k)
... else:
... for item in dict_flatten(d[k]):
... yield (item, k)
...
这将生成一组元组,因此不会丢失任何信息:
>>> for tup in reverse_nested_dict(d):
... print tup
...
('three', 'dict1')
('four', 'dict1')
('five', 'dict3')
('six', 'dict3')
('one', 'dict2')
('two', 'dict2')
如果您知道所有非映射值都是可散列的,并且知道它们是唯一的,或者您不关心冲突,那么只需将结果元组传递给dict:
要处理嵌套字典,我会像处理states一样 但是,如果将来它不包含嵌套字典,请非常小心地进行简单的反转。根据设计,字典键是唯一的,但值没有此要求 如果多个键的值相同,则在反转字典时,除一个键外,所有键都将丢失。由于字典没有排序,您可能会任意丢失不同的数据 反转工作示例: 反转故障示例:注意dict4是服务水平 t
要处理嵌套字典,我会像处理states一样 但是,如果将来它不包含嵌套字典,请非常小心地进行简单的反转。根据设计,字典键是唯一的,但值没有此要求 如果多个键的值相同,则在反转字典时,除一个键外,所有键都将丢失。由于字典没有排序,您可能会任意丢失不同的数据 反转工作示例: 反转失败示例:注意dict4丢失
这里有一个没有人想到的例子:可以类似地使用
raw_dict = { 'key1': 'val1', 'key2': 'val2', 'key3': 'val1' }
new_dict = {}
for k,v in raw_dict.items():
try: new_dict[v].append(k)
except: new_dict[v] = [k]
结果:
>>> new_dict
{'val2': ['key2'], 'val1': ['key3', 'key1']}
也许不是最好的方法,但它能满足我的需要。这里有一个没有人想到的例子:可以类似地使用
raw_dict = { 'key1': 'val1', 'key2': 'val2', 'key3': 'val1' }
new_dict = {}
for k,v in raw_dict.items():
try: new_dict[v].append(k)
except: new_dict[v] = [k]
结果:
>>> new_dict
{'val2': ['key2'], 'val1': ['key3', 'key1']}
也许不是最好的方法,但它可以满足我的需要。如果字典包含不可破坏的值,那么它就不起作用,因此它对问题中的示例不起作用。进一步扩展Peter的解释,字典不是一成不变的,因此不是哈希的,因此字典不能成为字典的键。如果对象的哈希值在其生命周期内从未更改,则该对象是可哈希的-Python词汇表。如果字典包含不可哈希的值,则该操作不起作用,因此对于问题中的示例不起作用。为了扩展Peter的解释,字典不是不变的,因此不可哈希,因此,字典不可能是字典的钥匙。如果一个对象的哈希值在其生命周期内从未改变,那么它就是可哈希的——Python词汇表。这个问题与Codemonk的响应相同——它没有回答这个问题。OP将d指定为一个字典,其值是字典,而不是字符串。与Codemonk的响应相同的问题-它没有回答问题。OP将d指定为字典,其值是字典,而不是字符串。