More pythonic way to filter objects from a list of dicts based on a dict value that must not contain a string from a list of strings

huangapple go评论90阅读模式
英文:

More pythonic way to filter objects from a list of dicts based on a dict value that must not contain a string from a list of strings

问题

作为来自Java的开发者,我想知道是否有一种更具Python风格的方法来实现以下逻辑:

movies = [{'original_title': 'Star Wars'}, {'original_title': 'Avengers'}, {'original_title': 'After Love'}]
blacklist = ['Star', 'Love']

filtered_movies = []
for movie in movies:
    blacklisted = False
    for item in blacklist:
        if item in movie['original_title']:
            blacklisted = True
            break
    if not blacklisted:
        filtered_movies.append(movie)

return filtered_movies

然后,filtered_movies 仅包含项目 {'original_title': 'Avengers'}

英文:

As I'm coming from Java, I wonder if there is a more pythonic approach to achieve the following logic:

movies = [{'original_title': 'Star Wars'}, {'original_title': 'Avengers'}, {'original_title': 'After Love'}]
blacklist = ['Star', 'Love']

filtered_movies = []
for movie in movies:
    blacklisted = False
    for item in blacklist:
        if item in movie['original_title']:
            blacklisted = True
            break
    if not blacklisted:
        filtered_movies.append(movie)

return filtered_movies

filtered_movies then only contains the item {'original_title': 'Avengers'}.

答案1

得分: 3

你可以使用 列表推导式 来实现这个操作:

filtered_movies = [movie for movie in movies 
                   if not any(
                      item in movie['original_title']
                      for item in blacklist
                   )]

例如:

>>> movies = [{'original_title': 'Star Wars'}, {'original_title': 'Avengers'}, {'original_title': 'After Love'}]
>>> blacklist = ['Star', 'Love']
>>> filtered_movies = [movie for movie in movies
... if not any(item in movie['original_title'] for item in blacklist)]
>>> filtered_movies
[{'original_title': 'Avengers'}]

这是执行此类过滤操作的一种常见方法;内置的 any 方法(在此处使用)和 all 方法在此非常有用。

英文:

You can do this with a list comprehension:

filtered_movies = [movie for movie in movies 
                   if not any(
                      item in movie['original_title']
                      for item in blacklist
                   )]

For example:

>>> movies = [{'original_title': 'Star Wars'}, {'original_title': 'Avengers'}, {'original_title': 'After Love'}]
>>> blacklist = ['Star', 'Love']
>>> filtered_movies = [movie for movie in movies
... if not any(item in movie['original_title'] for item in blacklist)]
>>> filtered_movies
[{'original_title': 'Avengers'}]

This is a pretty canonical way of performing this sort of filtering operation; the builtin any (used here) and all methods are particularly useful for this.

答案2

得分: 1

我会这样做,但不确定是否更符合Python的风格。

movies = [
    {'original_title': 'Star Wars'},
    {'original_title': 'Avengers'},
    {'original_title': 'After Love'},
]
blacklist = ['Star', 'Love']

filtered_movies = []
for movie in movies:
    if any(word in movie['original_title'] for word in blacklist):
        continue
    filtered_movies.append(movie)

print(filtered_movies)
英文:

I would have done it like this, but no idea if this is a more pythonic approach.

movies = [
    {'original_title': 'Star Wars'},
    {'original_title': 'Avengers'},
    {'original_title': 'After Love'},
]
blacklist = ['Star', 'Love']

filtered_movies = []
for movie in movies:
    if any(word in movie['original_title'] for word in blacklist):
        continue
    filtered_movies.append(movie)

print(filtered_movies)

答案3

得分: -2

以下是翻译好的部分:

这里使用了filter和lambda函数以及set

    >>> list(filter(lambda x: len(set(blacklist) & set(x["original_title"].split())) == 0, movies))
    [{'original_title': 'Avengers'}]

如果不允许拆分

    >>> list(filter(lambda x: len([1 for y in blacklist if y in x["original_title"]])==0, movies))
    [{'original_title': 'Avengers'}]
    >>> list(filter(lambda x: not any(1 for y in blacklist if y in x["original_title"]), movies))
    [{'original_title': 'Avengers'}]
英文:

Here you go using filter and lambda function and set

>>> list(filter(lambda x: len(set(blacklist) & set(x["original_title"].split())) == 0, movies))
[{'original_title': 'Avengers'}]

if splitting is not allowed then:

>>> list(filter(lambda x: len([1 for y in blacklist if y in x["original_title"]])==0, movies))
[{'original_title': 'Avengers'}]
>>> list(filter(lambda x: not any(1 for y in blacklist if y in x["original_title"]), movies))
[{'original_title': 'Avengers'}]

huangapple
  • 本文由 发表于 2023年1月9日 02:34:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050364.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定