【问题标题】:Return and delete all key-value pairs whose tuple keys contain a given element返回并删除所有元组键包含给定元素的键值对
【发布时间】:2012-07-20 00:36:14
【问题描述】:

给定一个由 2 元素元组作为键的字典,我想返回其键包含给定元素的所有键值对。

例如,字典可以是:

tupled_dict = {('a',1):1, ('a',2):0, ('b',1):1, ('c',4):0}

并且给定的元素是'a',那么应该返回的键值对将是:

('a',1):1, ('a',2):0

最快的代码是什么?

编辑:

此外,作为一个相关的子问题,我感兴趣的是在给定键元素的情况下删除所有此类键值对的最快方法。显然,一旦我有了上面的结果,我就可以使用循环将每个字典项一个一个地删除,但是我想知道是否有捷径可以做到。

【问题讨论】:

标签: python dictionary tuples


【解决方案1】:

要获得这些:

>>> {k: v for k, v in tupled_dict.iteritems() if 'a' in k}
{('a', 1): 1, ('a', 2): 0}

同样,删除其他的:

>>> tupled_dict = {k: v for k, v in tupled_dict.iteritems() if 'a' not in k}
>>> tupled_dict
{('b', 1): 1, ('c', 4): 0}

【讨论】:

  • 如果 dict 可以包含元组以外的键(例如,字符串),那么您可能需要将 in 关键字交换为不同的逻辑。
  • 如果我没记错的话,删除将创建一个新字典并将其分配给tupled_dict?就地删除呢?那会更快吗?
  • 这可能取决于将删除的条目的比例。你可以自己检查timeit
【解决方案2】:

我尚未对其性能进行测试,但我建议您先使用 for 循环获取基线,然后使用 dict comprehensions 获取另一个基线。

>>> {k:v for k, v in tupled_dict.iteritems() if k[0] == 'a'}
{('a', 1): 1, ('a', 2): 0}

【讨论】:

  • 严格解释问题,如果 'a' 是键元组的第二个元素,这将不起作用。
【解决方案3】:

即使 'a' 不是键元组中的第一个元素,这个 sn-p 也可以工作:

from operator import methodcaller

contains_a = methodcaller('__contains__', 'a')
keys = filter(contains_a, tupled_dict)
new_dict = dict(zip(keys, map(tupled_dict.get, keys))

【讨论】: