1

我试图排除返回无的理解的情况。以下实现了它,但导致调用该函数两次!!!

>>> 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]

出路是什么?

4

3 回答 3

4
result1[:] = [x for x in map(func, l) if x is not None]

在 Python 2.x 上使用itertools.imap

注意: filter(None, map(func, l))通常会起作用,但也会删除0(因为它被认为是空的)

于 2013-05-30T05:45:13.723 回答
2

这段代码怎么样:

print([x*2 for x in l if x <= 10])

编辑

通常它可以采取以下形式:

print([process(x) for x in l if is_valid(x)]
于 2013-05-30T05:54:18.530 回答
1
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结果的“样板”。

于 2013-05-30T08:19:40.507 回答