【问题标题】:Check length of list in list comprehension (Iteration based on the count of elements within list comprehension)检查列表理解中的列表长度(基于列表理解中元素计数的迭代)
【发布时间】:2018-08-13 07:59:30
【问题描述】:

我只需要计算前五个素数。我想在列表理解中构建列表时检查列表的长度。以下代码不起作用。

def checkPrime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True



 primes = [] 
 primes = [x  for x in range(2,30) if(checkPrime(x) and len(primes)<6) ] 
 print primes

输出:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

为什么len(primes)&lt;6 在这里不起作用。我怎样才能做到这一点?

【问题讨论】:

  • 您的新primes 正在创建中。您一直在检查空列表的长度。
  • 这是有道理的。如何在列表理解中检查长度或维护计数器?

标签: python python-2.7 list list-comprehension


【解决方案1】:

“Pythonic”方式是使用generator,加上islice 函数:

from itertools import islice

def checkPrime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def primes():
    i = 2
    while True:
        if checkPrime(i):
            yield i
        i += 1

first_5 = list(islice(primes, 5))

这将创建一个名为primes 的无限“列表”,您可以通过多种方式使用列表,但它只会实际计算您需要的值。

【讨论】:

  • 它抛出一个错误,说对象函数不是可迭代的
  • 您可能需要做list(first_5)。我将更新示例,使其自动成为列表。
【解决方案2】:

List Comprehension 创建并返回新列表。 在您的代码中,list comprehension 中,len(primes) 将始终返回零,因为在列表理解完成并返回新列表之前,列表的长度不会更新。

如果您必须使用 列表推导式,您可以创建一个 generator 函数来返回您的下一个素数范围。在列表理解中调用生成器对象上的next()(使用range 来限制所需值的计数)。

例如:

def checkPrime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

# Generator function
def getPrimes(n):
    for x in range(2, n):
        if(checkPrime(x)):
            yield x

# Create Generator object
primes_gen = getPrimes(30)

# List comprehension to get primes
primes = [next(primes_gen) for _ in range(5)]
#         ^                               ^ required count of prime numbers in list
#         ^ to get next prime number

primes 持有的最终值将是:

>>> primes
[2, 3, 5, 7, 11]

正如robbrit's answer 中所建议的那样,Pythonic 方法是使用itertools.islice (但它不是您要求的列表理解)

>>> from itertools import islice

#    v type-casting it to list for displaying the list, 
#    v   as `islice` also returns a generator object
>>> list(islice(getPrimes(30), 5))
[2, 3, 5, 7, 11]  # ^ generator function from my older example

【讨论】:

    【解决方案3】:

    使用itertools.islice 结合filter 让你的计算变得懒惰。

    from itertools import islice
    
    def checkPrime(n):
        for i in range(2,int(n**0.5)+1):
            if n%i==0:
                return False
        return True
    
    primes = filter(checkPrime, range(2, 10**100))
    
    list(islice(primes, 6))  # [2, 3, 5, 7, 11, 13]
    

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 2010-11-14
      相关资源
      最近更新 更多