我有这样的事情:
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)
它并没有删除所有非素数
我无法弄明白为什么
答案 0 :(得分:10)
在您的代码中:
def removeNonPrimes(palindromes):
for palindrom in palindromes:
if isPrime(palindrom):
palindromes.remove(palindrom)
return palindromes
您正在修改(使用.remove()
)您正在迭代的相同列表(使用in
)。不建议这样做,您最终可能会删除您想要的不同项目。
相反,请考虑列表理解:
def removeNonPrimes(palindromes):
return [p for p in palindromes if isPrime(p)]
答案 1 :(得分:4)
isPrime
的返回值与它们应该是的相反。
答案 2 :(得分:2)
您正在迭代迭代并同时修改该可迭代。因此,当一个循环完成时,指针可能不一定指向您正在迭代的原始集合中的下一个项目。
如果isPrime(palindrom)返回True并且您删除了一个项目,则列表的长度减少一个。
考虑一个情况,其中回文数= [7,8,9,10],而回文数值为8。 palindrom实际上指的是回文[1]。循环结束后,回文将指向回文[2]。 同时,由于它不是素数,因此将从回文中删除8。 现在palindromes = [7,9,10]和palindrom = palindromes [2] = 10.你可以看到值9永远不会被触及。
道德:永远不要操纵你迭代的迭代。这就像切割你所坐的树枝。
(顺便说一句,函数名称应该是isNotPrime而不是isPrime来反映它正在检查的内容。:))
答案 3 :(得分:0)
如果你想要所有的回文质数,这将更好:
def eras(n):
last = n + 1
sieve = [0,0] + list(range(2,last))
sqn = int(round(n ** 0.5))
it = (i for i in xrange(2, sqn + 1) if sieve[i])
for i in it:
sieve[i*i:last:i] = [0] * (n//i - i + 1)
return filter(None, sieve)
def is_palindrome(n):
ns = str(n)
ns_reversed = ''.join(reversed(ns))
return ns == ns_reversed
if __name__ == '__main__':
primes = eras(100 * 1000)
print [p for p in primes if is_palindrome(p)]