Python修改错误列表?

发布于 2024-10-06 04:53:06 字数 942 浏览 4 评论 0原文

我正在尝试使用 this 方法生成素数列表。我需要循环遍历每个数字 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'

I'm trying to generate a list of primes using the this method. I need to loop through every number 2...n and check it for multiples of 2...n. For some reason, the wrong list seems to be getting modified.

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

I get the following error:

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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

若能看破又如何 2024-10-13 04:53:06

你不是在复印。您使用的是引用,因此 copy1copy2copy3 都引用同一个列表 - sieve 。如果要复制,请使用:

copy1 = sieve[:]

这将创建 sieve 的副本并将其分配给 copy1

You're not making copies. You're using references, so copy1, copy2, and copy3 all refer to the same list -- sieve. If you want to copy, use:

copy1 = sieve[:]

which will create a copy of sieve and assign it to copy1.

好久不见√ 2024-10-13 04:53:06

您需要使用

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]

You need to use

copy1 = sieve[:] # tried making extra copies. . .
copy2 = sieve[:]
copy3 = sieve[:]

to actually copy the list. Otherwise you just copy the reference to the list.

>>> a = [1,2]
>>> b = a
>>> c = a[:]
>>> b[0] = 0
>>> c[0] = 3
>>> a
[0, 2]
>>> b
[0, 2]
>>> c
[3, 2]
白日梦 2024-10-13 04:53:06
copy1 = sieve
copy2 = sieve
copy3 = sieve

这些不是副本,而是参考。

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
copy1 = sieve
copy2 = sieve
copy3 = sieve

These are not copies they are reference's.

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

Is a good sieve method

More unit testing because its fun

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
如梦初醒的夏天 2024-10-13 04:53:06

Python 有引用语义。一般来说,a = b 会导致名称 a 引用与名称 b 当前引用的值相同的值。它不会创造或存储新的价值。

您可以使用提到的 [:] 技巧来克隆列表。复制内容的更通用的解决方案是使用 copy 模块。

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

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

Python has reference semantics. In general, a = b causes the name a to refer to the same value that the name b currently refers to. It does not create or store a new value.

You can clone a list with the [:] trick that was mentioned. A more general-purpose solution for copying things is to use the copy module.

However, good Python code normally does not require explicitly copying things very often. You should get familiar with using list comprehensions to create "modified versions" of existing sequences. For example, we can implement the sieve as (showing off a few other things as well):

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
碍人泪离人颜 2024-10-13 04:53:06

我无法对此进行测试,因为我没有 Python 3.2 的副本(argparse 是 Python 3.2 中的新功能),但我想到了两件明显的事情:

首先,您确实需要执行 <代码>sieve.append(int(i)) 。

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

copy1 = sieve[:]

I couldn't test this, because I don't have a copy of Python 3.2 (argparse is new in Python 3.2), but two obvious things come to mind:

First, you do need to do sieve.append(int(i)) .

Second, you aren't making a copy of sieve, you are simply creating a new reference to the same list. To make a copy, you need to

copy1 = sieve[:]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文