簡體   English   中英

在python中使用dict值獲取dict鍵

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM