我的問題是:如何使用字典值獲取字典密鑰?在python中使用字典值獲取字典密鑰
d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}}
我想dict2
的two
關鍵中的關鍵。
謝謝。
我的問題是:如何使用字典值獲取字典密鑰?在python中使用字典值獲取字典密鑰
d={'dict2': {1: 'one', 2: 'two'}, 'dict1': {3: 'three', 4: 'four'}}
我想dict2
的two
關鍵中的關鍵。
謝謝。
我不知道最好的解決方案,但有一種可能性是顛倒字典(使值成爲鍵),然後只是做一個普通的密鑰查找。這將扭轉詞典:
forward_dict = { 'key1': 'val1', 'key2': 'val2'}
reverse_dict = dict([(v,k) for k,v in forward_dict.items()])
因此給予 「VAL1」,我可以這樣做:
reverse_dict["val1"]
找到對應的按鍵。此解決方案存在明顯的問題 - 例如,如果您的值不唯一,您將失去一些信息。
編寫反轉字典的代碼(即創建一個將舊字典值映射到舊字典值的新字典)。
既然你似乎在處理嵌套字典,這顯然會更棘手。找出解決問題所需的最少數量和代碼(即,如果您的問題僅處理字典中沒有任何字典的字典,則不要創建任意嵌套深度的解決方案)
如果你不想扭轉字典,這裏的另一個可能的解決方案:
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
與Codemonk的迴應相同的問題 - 它不回答問題。 OP指定d是一個字典,其值是字典,而不是字符串。 – Dave
下面創建一個反向字典兩級例如:
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_recursive(d[k], target)
與False
的結果,因爲否則諸如''
之類的錯誤鍵會導致搜索失敗。事實上,即使此版本失敗,如果使用False
作爲關鍵字;完全一般的解決方案將使用唯一的哨點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'}
要處理的嵌套字典我會就像senderle's answer一樣。
但是,如果將來它不包含嵌套字典,請務必做一個簡單的逆轉。按設計字典鍵是唯一的,但值沒有這個要求。
如果您的多個鍵的值相同,則在翻轉字典時,您將失去,但其中除了一個。而且由於字典沒有排序,你可能會隨意丟失不同的數據。逆轉工作的
例子:
>>> 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'}
這裏是一個例子沒有人認爲有關:(可以同樣使用)
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']}
也許不是最好的方法,但它的工作原理爲我需要它。
如果字典包含不可取值,這不起作用,所以它不適用於問題中的示例。 –
爲了展開彼得的解釋,字典不是不可變的,因此不可散列,所以字典不能成爲字典的關鍵。 「如果一個對象具有在其生命週期中從不改變的哈希值,則該對象是可散列的」 - Python術語表。 – Dave