[英]getting dict key using dict value in python
我的問題是:如何使用字典值獲取字典密鑰?
d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}}
我想讓dict2
成為two
關鍵的關鍵。
謝謝。
這是一個可以處理任意嵌套字典的遞歸解決方案:
>>> 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_recursive(d[k], target)
與False
因為否則像''
這樣''
False
密鑰會導致搜索失敗。事實上,如果將False
用作密鑰,即使這個版本也會失敗;完全通用的解決方案將使用唯一的sentinel object()
來表示錯誤。)
一些用法示例:
>>> 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()
:
>>> dict(reverse_nested_dict(d))
{'six': 'dict3', 'three': 'dict1', 'two': 'dict2', 'four': 'dict1',
'five': 'dict3', 'one': 'dict2'}
如果您不想反轉字典,這是另一種可能的解決方案:
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'}
這是一個沒有人想到的例子:(可以類似地使用)
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']}
也許不是最好的方法,但它適用於我需要它。
我不知道最好的解決方案,但有一種可能性是反轉字典(以便值成為鍵),然后只進行正常的鍵查找。 這將顛倒字典:
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),那么就不要創建一個可以任意深度嵌套的解決方案
為了處理嵌套的詞典,我會像發送者的回答那樣做。
但是,如果將來它不包含嵌套字典,請非常小心地進行簡單的反轉。 根據設計,字典鍵是唯一的,但值不具備此要求。
如果多個鍵的值相同,則在反轉字典時, 除了其中一個鍵外,其他所有鍵都會丟失。 而且由於字典沒有排序,您可能會隨意丟失不同的數據。
逆轉工作的例子:
>>> d={'dict1': 1, 'dict2': 2, 'dict3': 3, 'dict4': 4}
>>> rd = dict([(v,k) for k,v in d.items()])
>>> print d
{'dict4': 4, 'dict1': 1, 'dict3': 3, 'dict2': 2}
>>> print rd
{1: 'dict1', 2: 'dict2', 3: 'dict3', 4: 'dict4'}
反轉失敗的示例:請注意dict4
丟失
>>> d={'dict1': 1, 'dict2': 4, 'dict3': 3, 'dict4': 4}
>>> rd = dict([(v,k) for k,v in d.items()])
>>> print d
{'dict4': 4, 'dict1': 1, 'dict3': 3, 'dict2': 4}
>>> print rd
{1: 'dict1', 3: 'dict3', 4: 'dict2'}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.