问题:过滤python词典中的项,其中键包含特定的字符串
我是用python开发东西的C编码器。我知道如何在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
回答 0
字典理解如何:
filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}
您所看到的它应该是不言自明的,因为它的英语读起来很好。
此语法要求Python 2.7或更高版本。
在Python 3中,只有iteritems()
所以您可以使用:
filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}
回答 1
选择最易读和易于维护的内容。仅仅因为您可以将其写成一行并不意味着您应该这样做。您现有的解决方案与我将要使用的迭代器跳过用户查找值的方法很接近,并且我讨厌如果不能避免,则使用嵌套的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
您可以使用内置的过滤器功能根据特定条件过滤字典,列表等。
filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))
优点是您可以将其用于不同的数据结构。
回答 3
input = {"A":"a", "B":"b", "C":"c"}
output = {k:v for (k,v) in input.items() if key_satifies_condition(k)}
回答 4
乔纳森(Jonathon)在他的回答中给了你运用字典理解的方法。这是处理您要做的事情的一种方法。
如果您想对字典的值做一些事情,则根本不需要字典理解:
我正在使用iteritems(
),因为您用标记了您的问题python-2.7
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(lambda a: a[0]*a[1], ((k,v) for k,v in {2:2, 3:2}.iteritems() if k == 2))
[4]