相当陌生的Python,仍在努力应对如此多的信息。
我所看到的关于词典的所有文档都解释了通过键获取值的各种方法 - 但我正在寻找一种相反的pythonic方法 - 通过值获取键。
我知道我可以遍历键并检查它们的值,直到找到我正在寻找的值,然后抓住键,但我正在寻找直接路线。
答案 0 :(得分:27)
没有直接路线。但是,列表推导很容易;
[k for k, v in d.iteritems() if v == desired_value]
如果您需要偶尔执行此操作,并且在将其编入索引时不要认为它值得,您可以执行以下操作:
class bidict(dict):
def key_with_value(self, value, default=None):
for k, v in self.iteritems():
if v == value:
return v
return default
def keys_with_value(self, value, default=None):
return [v for k, v in self.iteritems() if v == value]
然后d.key_with_value
表现得更像d.get
,除了反过来。
你也可以创建一个自动索引它的类。那么关键和价值都需要是可以清洗的。以下是三种实施方式:
在两个单独的词中,暴露了一些类似dict的方法;你也许可以做foo.by_key[key]
或foo.by_value[value]
。 (没有给出代码,因为它更复杂,而且我很懒,而且我认为这不是最理想的。)
在不同的结构中,您可以d[key]
和d.inverse[value]
:
class bidict(dict):
def __init__(self, *args, **kwargs):
self.inverse = {}
super(bidict, self).__init__(key, value)
def __setitem__(self, key, value):
super(bidict, self).__setitem__(key, value)
self.inverse[value] = key
def __delitem__(self, key):
del self.inverse[self[key]]
super(bidict, self).__delitem__(key)
在相同的结构中,您可以执行d[key]
和d[value]
:
class bidict(dict):
def __setitem__(self, key, value):
super(bidict, self).__setitem__(key, value)
super(bidict, self).__setitem__(value, key)
def __delitem__(self, key):
super(bidict, self).__delitem__(self[key])
super(bidict, self).__delitem__(key)
(值得注意的是bidict
的这些实现中缺少的是update
方法,它会稍微复杂一些(但help(dict.update)
将表明您需要覆盖的内容)。如果没有update
,bidict({1:2})
就不会按预期执行,也不会d.update({1:2})
。)
还要考虑其他一些数据结构是否更合适。
答案 1 :(得分:6)
由于您的字典可以包含重复值(即{'a': 'A', 'b': 'A'}
),因此从值中查找键的唯一方法是按照您的描述迭代字典。
或者......构建相反的字典。你必须在每次修改原始字典后重新创建它。
或者......编写一个维护双向字典的类。您必须管理出现重复值的情况。
答案 2 :(得分:1)
列表理解的第一个解决方案是好的。
但对于python 3.x的一个小修复,而不是for i,v in ipairs(result) do print(i,v) end
它应该只是.iteritems()
:
.items()
答案 3 :(得分:0)
构建一个相反的字典并不是很好,因为一个或多个键具有相同的值,但如果你反转它,你需要插入键:[value1,...]结构,这将导致你另一个问题。