Python函数返回生成器而不是列表

时间:2014-02-17 15:47:11

标签: python list python-3.x generator

我想在Python中使用素数,因此使用函数创建Sieve of Eratosthenes

def primes(limit):
    a = [True] * limit
    a[0] = a[1] = False

    for (i, isprime) in enumerate(a):
        if isprime:
            yield i
            for n in range(i*i, limit, i):
                a[n] = False
    return list(a)

在我看来,这个函数肯定应该返回一个列表但是当我print(primes(1000))时,我只得到<generator object primes at 0x0000000002C5C558>作为输出。使用print(list(primes(1000)))时,一切都按预期工作(打印质数列表)。

我缺少什么?

为什么函数返回生成器而不是列表?

4 个答案:

答案 0 :(得分:6)

因为您在函数中使用了yield expression

在筛子中,a是一个面具,而不是最终产生的素数列表。你不想真的回到那个名单。

如果您希望函数返回列表而不是充当生成器,请在函数中收集素数:

def primes(limit):
    a = [True] * limit
    a[0] = a[1] = False
    primes = []

    for (i, isprime) in enumerate(a):
        if isprime:
            primes.append(i)
            for n in range(i*i, limit, i):
                a[n] = False

    return primes

答案 1 :(得分:1)

Martijn打败了我。您正在返回return语句之前的yield表达式。

答案 2 :(得分:1)

要返回列表,您可以:

def primes(limit):
    result = []         # Store primes here.
    a = [True] * limit
    a[0] = a[1] = False

    for (i, isprime) in enumerate(a):
        if isprime:
            result.appen(i)
            for n in range(i*i, limit, i):
                a[n] = False
    return result      # return primes

答案 3 :(得分:1)

我刚刚遇到了类似的问题,想更新大家。如果函数在某个时间点屈服,即使您希望有一个列表,它也会返回一个生成器。因此,您需要摆脱收益。

def get_list_or_generator(return_list=True):
    items = [1, 2, 3, 4]
    if return_list:
        return items  # returns generator
    else:
        for item in items:
            yield item  # returns generator

它与list(get_list_or_generator())作为列表一起使用,因为casting to list iterates through the generator