Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python修改错误的列表?_Python_List_Primes_Nested Loops - Fatal编程技术网

Python修改错误的列表?

Python修改错误的列表?,python,list,primes,nested-loops,Python,List,Primes,Nested Loops,我试图用这个方法生成一个素数列表。我需要遍历每个数字2…n,并检查它是否是2…n的倍数。出于某种原因,错误的列表似乎正在被修改 import sys import argparse import math parser = argparse.ArgumentParser(description='find the largest prime factor of a number') parser.add_argument('n', type=int, help='number') args =

我试图用这个方法生成一个素数列表。我需要遍历每个数字2…n,并检查它是否是2…n的倍数。出于某种原因,错误的列表似乎正在被修改

import sys
import argparse
import math

parser = argparse.ArgumentParser(description='find the largest prime factor of a number')
parser.add_argument('n', type=int, help='number')
args = parser.parse_args()

sieve = []
for i in range(2,args.n+1): sieve.append(i) # tried int(i)


copy1 = sieve # tried making extra copies. . .
copy2 = sieve
copy3 = sieve
#print int(math.sqrt(args.n))

for index, i in enumerate(copy1):
    #print index, i
    for ii in copy2:
        #print ii
        if i % ii == 0:
            sieve[index]= None


print sieve
我得到以下错误:

Traceback (most recent call last):  
  File "3.py", line 22, in <module>
    if i % ii == 0: TypeError: unsupported operand type(s) for %:
'int' and 'str'
回溯(最近一次呼叫最后一次):
文件“3.py”,第22行,在
如果i%ii==0:TypeError:不支持%的操作数类型:
“int”和“str”

您没有复制。您正在使用引用,因此
copy1
copy2
copy3
都引用相同的列表--
sieve
。如果要复制,请使用:

copy1 = sieve[:]
它将创建一个
sieve
的副本,并将其分配给您需要使用的
copy1

copy1 = sieve[:] # tried making extra copies. . .
copy2 = sieve[:]
copy3 = sieve[:]
要真正复制列表。否则,只需将引用复制到列表

>>> a = [1,2]
>>> b = a
>>> c = a[:]
>>> b[0] = 0
>>> c[0] = 3
>>> a
[0, 2]
>>> b
[0, 2]
>>> c
[3, 2]
这些不是副本,它们是参考的

primes = [2,3,5,7]

def is_prime(n):
    if n in primes:
        return True
    for item in primes:
        if n % item == 0:
            return False
    return True

assert is_prime(4) == False
assert is_prime(29) == True
assert is_prime(65) == False
这是一种很好的筛分方法

更多的单元测试,因为它很有趣

true_primes = [int(item) for item in '11,13,17,19,23,29,31,37,41,43,47'.split(',')]
for item in xrange(10, 50):
    if is_prime(item) == True:
        assert item in true_primes
    else:
        assert item not in true_primes

我无法测试这一点,因为我没有Python 3.2的副本(
argparse
在Python 3.2中是新的),但我想到了两件显而易见的事情:

首先,您确实需要执行
sieve.append(int(i))

其次,您并不是在复制sieve,您只是在创建对同一列表的新引用。要复制,您需要

copy1 = sieve[:]

Python具有引用语义。通常,
a=b
会导致名称
a
引用与名称
b
当前引用的值相同的值。它不会创建或存储新值

您可以使用前面提到的[:]技巧克隆列表。复制东西的一个更通用的解决方案是使用
copy
模块

然而,好的Python代码通常不需要经常显式地复制东西。您应该熟悉使用列表理解来创建现有序列的“修改版本”。例如,我们可以将筛子实现为(展示其他一些东西):

import sys、argparse、math、itertools
parser=argparse.ArgumentParser(description='find the magnize prime factor of a number')
add_参数('n',type=int,help='number'))
args=parser.parse_args()
#使用“范围”上的循环来用递增的值填充列表是愚蠢的,因为
#范围*是*递增值的列表-这就是“for i in…”位的工作方式。
筛=范围(2,参数n+1)
#我们根本不需要记住原始循环。
#相反,我们依赖于筛的每次迭代,在开始时放置一个新的素数。
对于itertools.count()中的索引:#向上计数,
如果索引>=len(筛):打破#直到元素用完,
prime=sieve[index]#我们从列表中获取下一个prime,
sieve=[x代表sieve中的x,如果x==素数或x%素数!=0]#并用它筛选列表。
#当然,我们可以通过检查prime
这种混淆非常普遍。。。关于该语言的所有材料(以及所有具有类似语义的语言,顺便说一句)都应该包含一个巨大的红色框,其中包含该内容的摘要。delnan:另外,还有一个描述浮点算术工作原理的框。:-)在java中,String==String不是您想要做的。我注意到您正在使用Python3.x,在这种情况下,
range
实际上就是Python2.x中的
xrange
。为了解决这个问题,我们可以做一些类似于
sieve=list(范围(2,args.n+1))
,显式地列出生成器。
copy1 = sieve[:]
import sys, argparse, math, itertools

parser = argparse.ArgumentParser(description='find the largest prime factor of a number')
parser.add_argument('n', type=int, help='number')
args = parser.parse_args()

# Using a loop over a 'range' to fill a list with increasing values is silly, because
# the range *is* a list of increasing values - that's how the 'for i in ...' bit works.
sieve = range(2, args.n + 1)

# We don't need to remember the original loop at all.
# Instead, we rely on each iteration of the sieve putting a new prime at the beginning.
for index in itertools.count(): # Counting upward,
  if index >= len(sieve): break # until we run out of elements,
  prime = sieve[index] # we grab the next prime from the list,
  sieve = [x for x in sieve if x == prime or x % prime != 0] # and sieve the list with it.
# Of course, we can optimize that by checking that prime < sqrt(args.n), or whatever.

print sieve