通过值获取键,字典,Python

10

如何从值中获取键?

我的字典:

countries = {
        "Normal UK project" : "1",
        "UK Omnibus project" : "1-Omni",
        "Nordic project" : ["11","12","13","14"],
        "German project" : "21",
        "French project" : "31"
        }

我的代码有些问题:

for k, v in countries.items():
    if "1" in v:
        print k

期望输出:

Normal UK project

实际输出:

French project
UK Omnibus project
German project
Normal UK project

如何修复我的代码?


6
如果"1"等于v: - thefourtheye
如果我要查找的值是“12”,那么它将失败。 - Boosted_d16
3
首先,您应该统一您的值的类型。有些是字符串,有些是列表。最好只使用列表(某些仅具有一个元素),那么您的代码实际上将正常工作。 - tobias_k
3
如果你经常发现自己试图从值获取键,也许字典的结构是颠倒的? - jonrsharpe
1
我认为这是 https://dev59.com/Imsz5IYBdhLWcg3wQFe2 的重复。 - nofinator
显示剩余4条评论
7个回答

8

c={} - 任何字典
a(value) - 需要知道此键

key=list(c.keys())[list(c.values()).index(a)]

这是可行的,但 .index() 仅会返回 ca 的第一个实例。 - brittohalloran

7

问题在于字典中数值的类型不同,使得使用字典变得更加困难,而不仅仅是在这种情况下。虽然Python允许这样做,但你真的应该考虑统一字典中数值的类型,例如将它们全部改为列表。你只需一行代码就可以实现:

countries = {key: val if isinstance(val, list) else [val] 
                        for key, val in countries.items()}

现在,每个单独的字符串都被包装在一个列表中,您现有的代码将正常工作。
或者,如果您必须使用当前形式的字典,则可以调整查找函数:
for k, v in countries.items():
    if "1" == v or isinstance(v, list) and "1" in v:
        print k

4
以下代码提供了另一种通过某个值获取字典键的简短版本,使用列表推导和dic.items():
keys_have_value = [k for k,v in dic.items() if v=="1"]

仅提供代码的答案是不被鼓励的,因为它们显示了对问题回答的不充分尝试。 - Pandemonium

3
def keys_of_value(dct, value):
    for k in dct:
        if isinstance(dct[k], list):
            if value in dct[k]:
                return k
        else:
            if value == dct[k]:
                return k

assert keys_of_value(countries, "12") == "Nordic project"
assert keys_of_value(countries, "1")  == "Normal UK project"

如果您希望我稍微简化一下,我可以这么做。
from operator import eq, contains

def keys_of_value(dct, value, ops = (eq, contains)):
    for k in dct:
        if ops[isinstance(dct[k], list)](dct[k], value):
            return k

assert keys_of_value(countries, "12") == "Nordic project"
assert keys_of_value(countries, "1") == "Normal UK project"

感谢您的努力,非常感激。 - Boosted_d16

2
你的代码存在问题,导致返回了其他值。这是由于输入的数据类似于:
    "Normal UK project" : "1",

..然后 "1" in v 检查字符串中是否包含字符“1”,而对于类似以下的条目:

    "Nordic project" : ["11","12","13","14"],

然后它会检查列表中是否包含元素"1"。

in运算符适用于字符串和列表,但使用方式不同:

>>> "1" in "123"
True
>>> "1" in ["123", "blah"]
False
>>> "1" in ["1", "blah"]
True

理想情况下,您的数据应更加一致 - 全部为列表或全部为字符串:
countries = {
        "Normal UK project" : ["1"],
        "UK Omnibus project" : ["1-Omni"],
        "Nordic project" : ["11","12","13","14"],
        "German project" : ["21"],
        "French project" : ["31"]
        }

for k, v in countries.items():
    if "1" in v:
        print k

我本来想这样做,但我不确定是否正确,因为似乎有一个只有一个项目的列表有点多余。 - Boosted_d16

0
def get_Value(dic,value):
    for name in dic:
        if dic[name] == value:
            return name

0

我个人认为使用in和函数values更容易。

print 1 in {1:"123", 2:"blah"}
print "blah" in {1:"123", 2:"blah"}.values()

输出为:

True
True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接