繁体   English   中英

过滤地图与列表理解

[英]filter map vs list comprehension

过滤器/地图是否等同于列表理解? 假设我有以下功能

def fib_gen():
    a,b = 0,1
    yield 0
    yield 1
    while True:
        a,b = b,a+b
        yield b

现在我可以使用list comprehension列出fib数:

a = fib_gen()
print [a.next() for i in range(int(sys.argv[1]))]

假设我只想列出偶数的fib数。 我会使用filter / map执行以下操作:

a = fib_gen()
print filter(even, map(lambda x: a.next(), range(int(sys.argv[1]))))

如何通过列表理解获得相同的结果?

过滤器/地图是否等同于列表理解?

是的, map(f, L)相当于[f(x) for x in L] filter(f, L)相当于[x for x in L if f(x)] 但是,由于具有副作用的列表推导通常很糟糕(在这里你修改了生成器的状态),你可以使用itertools来获得更清洁的解决方案:

 a = fib_gen()
 a = itertools.islice(a, int(sys.argv[1]))
 a = itertools.ifilter(even, a)
 print list(a)

您可以使用生成器来存储中间结果,并在其上“过滤”。

fibs = (a.next() for i in whatever)
even_fibs = [num for num in fibs if num % 2 == 0]

或者在一行中:

even_fibs = [num for num in (a.next() for i in whatever) if num % 2 == 0]

请注意,如果要从迭代器中获取一定数量的元素,可以使用itertools.islice

from itertools import islice
fibs_max_count = int(sys.argv[1])
even_fibs = [num for num in islice(fib_gen(), fibs_max_count) if num%2 == 0]

filtermap很容易转换为列表理解。

这是一个基本的例子:

[hex(n) for n in range(0, 100) if n > 20]

这相当于:

list(map(hex, filter(lambda x: x > 20, range(0, 100))))

在我看来,理解更具可读性。 但是,如果条件变得非常先进,我更喜欢filter

所以在你的情况下:

[n for n in itertools.islice(fib_gen(), 100) if even(n)]

我在这里使用了islice ,因为序列是无限的。 但是如果使用生成器表达式,它也会成为无限流:

gen = (n for n in fib_gen() if even(n))

现在你可以使用islice对序列进行islice

print itertools.islice(gen, int(sys.argv[1]))

这避免了在理解本身中使用next的需要。 只要您不尝试评估无限序列(就像我们在列表islice中省略了islice那样),我们就可以使用您的序列。

我不认为这适用于发电机。 为了使这个工作与列表理解,你需要有:

print [a.next() for i in range(int(sys.argv[1])) if even(a.next())]

返回:

[1, 3, 13, 55, 233]

问题是您需要访问列表中下一个数字的两倍,但第二个a.next()调用会使它应该执行的操作,即获取下一个数字。 据我所知,不可能将带有列表推导的a.next()值存储两次。

您可以使用以下代码:

a = fib_gen()
print [a.next() for i in range(int(sys.argv[1])) if i%3==0]

这是一个特殊的情况,因为每个第三个fibbonacci数是偶数。

您也可以始终生成均匀的fibo数字......

def evenfib():
    """ Generates the even fibonacci numbers """
    a, b = 2, 0
    while True:
        a, b = b, a+4*b
        yield a

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM