过滤python字典中的项,其中键包含特定字符串

时间:2014-05-26 03:46:05

标签: python python-2.7 dictionary filtering

我是一名C编码员,用python开发一些东西。我知道如何在C中执行以下操作(因此在应用于python的C类逻辑中),但我想知道' Python'做到这一点的方式是。

我有一个字典d,我想操作一个项目的子集,只有那些键(字符串)包含一个特定的子字符串。

即。 C逻辑将是:

for key in d:
    if filter_string in key:
        # do something
    else
        # do nothing, continue

我想象python版本会像

filtered_dict = crazy_python_syntax(d, substring)
for key,value in filtered_dict.iteritems():
    # do something

我在这里发现了很多关于过滤词典的帖子,但是找不到涉及过这个词典的帖子。

我的词典没有嵌套,我使用的是python 2.7

5 个答案:

答案 0 :(得分:145)

dict comprehension

怎么样?
filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}

你看到它,它应该是不言自明的,因为它读得很像英语。

此语法需要Python 2.7或更高版本。

在Python 3中,只有dict.items(),而不是iteritems()所以你会使用:

filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}

答案 1 :(得分:14)

去寻找最易读和易于维护的内容。仅仅因为你可以用一行写出来并不意味着你应该这样做。您现有的解决方案接近我将使用的其他用户iteritems跳过值查找,我讨厌嵌套ifs,如果我可以避免它们:

for key, val in d.iteritems():
    if filter_string not in key:
        continue
    # do something

但是如果你真的想让某些东西让你迭代一个过滤后的dict,那么我就不会做两步构建过滤后的dict然后迭代它,而是使用一个生成器,因为什么是pythonic(和真棒)比发电机好吗?

首先我们创建我们的生成器,良好的设计要求我们将其抽象为足以重复使用:

# The implementation of my generator may look vaguely familiar, no?
def filter_dict(d, filter_string):
    for key, val in d.iteritems():
        if filter_string not in key:
            continue
        yield key, val

然后我们可以使用生成器通过简单易懂的代码很好地解决您的问题:

for key, val in filter_dict(d, some_string):
    # do something

简而言之:发电机很棒。

答案 2 :(得分:8)

input = {"A":"a", "B":"b", "C":"c"}
output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}

答案 3 :(得分:7)

Jonathon在his answer中使用dict理解为你提供了一种方法。这是一种处理做某事部分的方法。

如果你想对字典的值做一些事情,你根本不需要字典理解:

我正在使用iteritems(),因为您使用 标记了您的问题

results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k])

现在,结果将显示在列表中,some_function应用于字典的每个键/值对,其键中包含foo

如果您只想处理值并忽略键,只需更改列表理解:

results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k])

some_function可以是任何可调用的,因此lambda也可以工作:

results = map(lambda x: x*2, [v for k,v in a_dict.iteritems() if 'foo' in k])

实际上不需要内部列表,因为您也可以将生成器表达式传递给map:

>>> map(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))
[4]

答案 4 :(得分:5)

您可以使用内置filter function根据特定条件过滤字典,列表等。

filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))

优点是您可以将它用于不同的数据结构。