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

mem*_*emo 78 python dictionary filtering python-2.7

我是一名C编码员,用python开发一些东西.我知道该怎么做在C以下(因此在应用于蟒类似C的逻辑),但我不知道做什么的"Python的"事情是这样的.

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

即C逻辑将是:

for key in d:
    if filter_string in key:
        # do something
    else
        # do nothing, continue
Run Code Online (Sandbox Code Playgroud)

我想象python版本会是这样的

filtered_dict = crazy_python_syntax(d, substring)
for key,value in filtered_dict.iteritems():
    # do something
Run Code Online (Sandbox Code Playgroud)

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

我的字典没有嵌套,我正在使用python 2.7

Jon*_*art 157

字典理解怎么样:

filtered_dict = {k:v for k,v in d.iteritems() if filter_string in k}
Run Code Online (Sandbox Code Playgroud)

你看到它,它应该是不言自明的,因为它读起来像英语很好.

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

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

filtered_dict = {k:v for (k,v) in d.items() if filter_string in k}
Run Code Online (Sandbox Code Playgroud)

  • @thefourtheye我打算*猜测我的速度更快,因为它不会出现'd [k]`查找. (5认同)
  • 为什么不`filtered_dict = {k:d[k] for k in d if filter_string in k}`? (2认同)
  • 在 Python 3 中,您将用 `items` 替换 `iteritems`,这与 Python 2.7 的 `iteritems` 相同。 (2认同)

Bre*_*n F 15

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

for key, val in d.iteritems():
    if filter_string not in key:
        continue
    # do something
Run Code Online (Sandbox Code Playgroud)

但是如果你真的想让某些东西让你迭代一个过滤后的字典那么我就不会做两步构建过滤后的字典然后迭代它,而是使用一个生成器,因为什么比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
Run Code Online (Sandbox Code Playgroud)

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

for key, val in filter_dict(d, some_string):
    # do something
Run Code Online (Sandbox Code Playgroud)

简而言之:发电机很棒.


jsp*_*rim 8

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

  • 使用`iteritems()`的方法比`items()`更有效. (3认同)
  • 仅在 Python 2.7 上。在 Python 3 中*只有*`items()`,它的作用类似于 Python 2.7 的 `iteritems`。 (2认同)

小智 8

您可以使用内置函数“filter()”:

data = {'aaa':12, 'bbb':23, 'ccc':8, 'ddd':34}

# filter by key
print(dict(filter(lambda e:e[0]=='bbb', data.items() ) ) )

# filter by value
print(dict(filter(lambda e:e[1]>18, data.items() ) ) )
Run Code Online (Sandbox Code Playgroud)

输出:

data = {'aaa':12, 'bbb':23, 'ccc':8, 'ddd':34}

# filter by key
print(dict(filter(lambda e:e[0]=='bbb', data.items() ) ) )

# filter by value
print(dict(filter(lambda e:e[1]>18, data.items() ) ) )
Run Code Online (Sandbox Code Playgroud)


Bur*_*lid 7

Jonathon在他的回答中使用了dict理解给了你一个方法.这是一种处理你做某事的方法.

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

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

results = map(some_function, [(k,v) for k,v in a_dict.iteritems() if 'foo' in k])
Run Code Online (Sandbox Code Playgroud)

现在,结果将存在于列表中,该列表some_function应用于字典中的每个键/值对,该列foo在其键中.

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

results = map(some_function, [v for k,v in a_dict.iteritems() if 'foo' in k])
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


Pul*_*kit 7

您可以使用内置的过滤器功能根据特定条件过滤字典,列表等。

filtered_dict = dict(filter(lambda item: filter_str in item[0], d.items()))
Run Code Online (Sandbox Code Playgroud)

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