有没有办法使用python列表理解更新列表的值?

问题描述

例如:primes = [0,-1,-1] #here primes is a list

现在我想更新素数的值。正确工作的迭代如下。

for i in range(2,int(n ** 0.5) + 1):    
 for j in range(i,n,i):
  if(primes[j] == -1):
   primes[j] = i

这里 n = 10,i = 2。所以基本上迭代从 i 开始,以 i 为增量进行到 10。 例如,如果我们从 j=i=2 开始,那么在第一次迭代之后,我们将增加 2 并查找是否 primes[j] == -1。这将导致在第一次迭代后出现。

素数[0,2,2]。

在第二次迭代后,当 i 变为 3 时,现在如果 primes[j] == -1 将更新 3 的倍数,我们将在第二次迭代后得到以下结果。

素数[0,3,2]

我想知道一种内循环的方法,可以写成下面的形式。 (下面的形式称为python列表理解。我想使用python列表理解或使用切片方法更新值。)

primes[i : n: i] = [i for j in range(i,i) if primes[j] == -1]

它给了我如下错误

ValueError: 尝试将大小为 2 的序列分配给大小为 3 的扩展切片

解决方法

也不知道你为什么要这样做,但这不取决于我:

for i in range(2,int(n ** 0.5) + 1):
    primes[i : n: i] = [i if primes[j]==-1 else primes[j] for j in range(i,n,i) ]
,

问题在于,通过在列表理解中进行过滤,您最终分配的元素少于目标下标的大小。您需要匹配下标中的位置数,即使这意味着重新分配当前值。

你可以这样做:

primes[i : n: i] = [ [primes[j],i][primes[j]==-1] for j in range(i,i) ] 

primes[i : n: i] = ( i if p<0 else p for p in primes[i:n:i] )

请注意,为了提高效率,您的循环应该跳过不是素数的值,因为它们永远不会更新素数中的任何条目(假设它们已被先前的素数赋值):

primes = [0,0]+[-1]*(n-1)
for i in range(2,int(n ** 0.5) + 1):
    if primes[i]<0:
       primes[i::i] = (i if p<0 else p for p in primes[i::i])    

这也将导致 primes 中的每个位置包含相应数字的最小素因数(最多 √n),但它会更快。

使用 -1 作为不可见因素的约定可能并不理想。例如,您可以使用每个数字在其自己的位置初始化列表。这样,您在 n 的平方根处停止未覆盖的位置将包含相应的数字,该数字也恰好是其自身的最小素数除数:

primes = list(range(n+1))
for i in range(2,int(n ** 0.5) + 1):
    if primes[i]<i: continue
    primes[i*i::i] = (min(i,p) for p in primes[i*i::i])

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...