我试图排除返回无的理解的情况。以下实现了它,但导致调用该函数两次!!!
>>> def func(x):
... if x>10:
... return None
... else:
... return x*2
...
>>> result1=[func(x) for x in l if func(x) is not None]
>>> result1
[4, 8, 14, 6]
出路是什么?
我试图排除返回无的理解的情况。以下实现了它,但导致调用该函数两次!!!
>>> def func(x):
... if x>10:
... return None
... else:
... return x*2
...
>>> result1=[func(x) for x in l if func(x) is not None]
>>> result1
[4, 8, 14, 6]
出路是什么?
result1[:] = [x for x in map(func, l) if x is not None]
在 Python 2.x 上使用itertools.imap
注意: filter(None, map(func, l))
通常会起作用,但也会删除0
(因为它被认为是空的)
这段代码怎么样:
print([x*2 for x in l if x <= 10])
编辑
通常它可以采取以下形式:
print([process(x) for x in l if is_valid(x)]
def func(x):
if x>10:
return None
else:
return x*2
lst = [2, 4, 12, 7, 30, 3]
# original
result0 = [func(x) for x in lst if func(x) is not None]
# map... on Python 2.x, use itertools.imap()
result1 = [x for x in map(func, lst) if x is not None]
assert result1 == result0
# generator expression
result2 = [x for x in (func(y) for y in lst) if x is not None]
assert result2 == result0
# rewrite function as a generator function
def func_gen(iterable):
for x in iterable:
if x <= 10:
yield x*2
# no need to filter; filtering happens in generator function
result3 = list(func_gen(lst))
assert result3 == result0
# build a filtering generator out of parts
def fn_x2(x):
return x * 2
def filter_leq10(x):
return x <= 10
def make_filtering_gen_func(fn, flt, name="anonymous"):
def anonymous(iterable):
for x in iterable:
if flt(x):
yield fn(x)
anonymous.__name__ = name
return anonymous
func_gen1 = make_filtering_gen_func(fn_x2, filter_leq10)
result4 = list(func_gen1(lst))
assert result4 == result0
评论。
@jamylak 已经向您展示了如何使用map()
or解决它itertools.imap()
。但由于某种原因,他/她展示了使用切片重写现有列表。我看不出有任何理由这样做,所以我只是通过绑定到一个变量名来展示它。
更普遍推荐的替代方法map()
是生成器表达式,所以我展示了如何在列表推导中使用它。
但是对于这样的情况,我通常更喜欢将函数重写为只产生所需数字的生成器。无论如何,您都会调用该函数,因此不要让它为不需要的值返回一个哨兵值,而是让它只产生想要的值。
最后,用零件构建过滤生成器的功能性方法!你可以传入任何接受一个参数的函数(记住你可以functools.partial()
用来绑定其他参数并获取一个只接受一个参数的函数对象),还可以传入一个选择值的过滤器函数。它构建一个函数对象并返回它,它会自动为您处理添加for
循环、if
过滤测试以及yield
结果的“样板”。