具有列表理解的不同模式

ffl*_*ing 4 python list-comprehension

我面临一个特殊的问题,最近我觉得需要生成某种类型的列表理解。

例如:

[ re.search('xyz', l).group(0) for l in my_list if re.search('xyz', l) ]
Run Code Online (Sandbox Code Playgroud)

现在,敏锐的读者可能已经观察到这个列表理解进行了正则表达式匹配两次。

我想消除这种“额外”开销,从而失去列表理解的优雅性。以前有人遇到过这样的问题吗?如果是这样,他们是如何解决这个问题的?

一般来说,我有一个f()应用于x列表中的值/对象的函数,现在我希望f(x).b当且仅当f(x).a满足某些条件时才将其包含在我的列表中。

我知道

empty_list = []
for l in my_list:
    match = re.search('xyz', l)
    if match:
        empty_list.append(match.group(0))
Run Code Online (Sandbox Code Playgroud)

或者更一般地说:

empty_list = []
for x in my_list:
    val = f(x)
    if val.a == condition:
        empty_list.append(val.b)
Run Code Online (Sandbox Code Playgroud)

是一个可能的解决方案,但这似乎太冗长了,我确信有一种更“Pythonic”的方法可以做到这一点。

Tri*_*ych 5

使用生成器推导式:

# Your original list of data.
my_list = []

# This 'knows' how to produce a new list of elements where each 
# element satisfies some test, here represented as `predicate`.
# Looks like a list comprehension, but note the surrounding parens.
passing = (x for x in my_list if predicate(x))

# This knows how to apply some function `f` to each element in the list.
mapped = (f(x) for x in passing)

# Now use the know-how above to actually create your list.
# Note that because you're using chained generators, you are 
# only iterating over the original list once!
results = list(mapped)

# Or if you don't need all the intermediate values at once...
for el in mapped:
  do_something_with(el)
Run Code Online (Sandbox Code Playgroud)