从列表中移除非素数数值
我有这样的代码:
palindromes=[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 101, 111, 121, ..., 99799, 99899, 99999]
# of course im generating it :)
def isPrime(number):
for i in range(2,int(number/2)+1):
if number%i == 0:
return True
return False
def removeNonPrimes(palindromes):
for palindrom in palindromes:
if isPrime(palindrom):
palindromes.remove(palindrom)
return palindromes
palindromes = removeNonPrimes(palindromes)
但是它没有把所有的非质数都去掉。
我搞不清楚为什么会这样。
4 个回答
2
你在遍历一个可遍历的对象(比如列表)时,同时又在修改这个对象。所以当一个循环结束后,指针可能并不指向你原本正在遍历的下一个项目。
如果函数isPrime(palindrom)返回True,而你又删除了一个项目,那么列表的长度就会减少一个。
想象一下,如果palindromes = [7,8,9,10],而palindrom的值是8。palindrom实际上指向的是palindromes[1]。当循环结束后,palindrom会指向palindromes[2]。与此同时,由于8不是质数,它会被从palindromes中删除。现在palindromes变成了[7,9,10],而palindrom = palindromes[2] = 10。你可以看到,值为9的项目根本没有被处理。
这个教训是:在遍历一个对象时,千万不要对它进行修改。这就像是你坐在树上,却去砍那棵树的树枝。
(顺便说一下,函数的名字应该是isNotPrime,而不是isPrime,这样更能反映它在检查什么。:))
4
你在isPrime
这个函数里的返回值跟应该返回的正好相反。
11
在你的代码中:
def removeNonPrimes(palindromes):
for palindrom in palindromes:
if isPrime(palindrom):
palindromes.remove(palindrom)
return palindromes
你在遍历一个列表的时候,同时又在修改这个列表(用的是.remove()
)。这样做是不太推荐的,因为你可能会意外地删除一些你不想删除的东西。
相反,你可以考虑使用一种叫做列表推导式的方法:
def removeNonPrimes(palindromes):
return [p for p in palindromes if isPrime(p)]