简体   繁体   中英

Why does my simple program to list primes tell me that "builtin_function_or_method" object is not subscriptable?

The program gets stuck at line 7 and prints the error

"'builtin_function_or_method' object is not subscriptable"

It's likely there is more errors with this code because I'm a complete newbie, if you spot any please point them out.

i = 3
primes = [2]
remainder = []
while i <= 20:
    for x in primes:
        remainder.append[i%x]
    if all(remainder!= 0) == True:
        primes.append(i)
    i += 1
    remainder.clear()
print(primes)

What I want the code to do is to iterate through the numbers 3 to 20, each time checking to see if i is prime by dividing by all known primes, if it is prime I want the code to append it to the list of known primes so that it can be used in testing the primality of further values of i.

Exchange append[i%x] with append(i%x) . append is a built-in method. The square brackets [] are used for subsetting / indexing. Call the function instead by using parentheses () .

So, for instance, the following code would work:

primes = [2]
remainder = []
for i in range(3, 21): # range slightly more often used than while loops

    for x in primes:
        remainder.append(i%x)

    if all(remainder): # note: no reason to add "== True". See PEP8.
        primes.append(i)

    remainder.clear()
print(primes)

There are two problems with your code right now.

First, you need to replace [] by () since append is a function.

Secondly, in your present implementation, you will get a TypeError: 'bool' object is not iterable while checking all() . You can simply do all(remainder) as suggested by @ShadowRanger .

i = 3
primes = [2]
remainder = []
while i <= 20:
    for x in primes:
        remainder.append(i%x)
    if all(remainder) == True:
        primes.append(i)
    i += 1
    remainder.clear()
print(primes)
# [2, 3, 5, 7, 11, 13, 17, 19]

Another alternative as suggested again in the comments is to use

all(rem != 0 for rem in remainder) 

where you use a for loop checking for each element in your remainder list. rem != 0 will give you True/False depending on if the condition is fulfilled or not. all will simply check if all enteries are True in which case it will return True else False if even a single entry is False.

If you want to get a feel of how all() is working here, put a print statement with the following output. As you can see, the output is False for only those cases where there exists even a single 0 and True where there is no 0.

print (remainder, all(remainder))

[1] True
[0, 1] False
[1, 2] True
[0, 0, 1] False
[1, 1, 2] True
[0, 2, 3, 1] False
[1, 0, 4, 2] False
[0, 1, 0, 3] False
[1, 2, 1, 4] True
[0, 0, 2, 5, 1] False
[1, 1, 3, 6, 2] True
[0, 2, 4, 0, 3, 1] False
[1, 0, 0, 1, 4, 2] False
[0, 1, 1, 2, 5, 3] False
[1, 2, 2, 3, 6, 4] True
[0, 0, 3, 4, 7, 5, 1] False
[1, 1, 4, 5, 8, 6, 2] True
[0, 2, 0, 6, 9, 7, 3, 1] False

The problem is the statement remainder.append[i%x] . In order to append something to the list, it should be done like this remainder.append(i%x) .

The correct code is:

i = 3
primes = [2]
remainder = []
while i <= 20:
    for x in primes:
        remainder.append(i%x)
    if all([item !=0 for item in remainder]) == True:
        primes.append(i)
    i += 1
    remainder.clear()
print(primes)

An alternative implementation could be:

def is_prime(n):
    """
    Check whether the given number is prime or not.
    """
    # we dont need to check all the range of numbers
    # from [2, n). We need to check in the set [2, n/2]
    # Note: there is an even better approximation
    for num in range(2, n/2 + 1):
        if n % num == 0:
            return False
    else:
        return True

def all_primes(limit):
    """
    Find all prime numbers in the range [2, limit)
    """
    primes = []

    for num in range(2, limit):
        if is_prime(num):
            primes.append(num)

    return primes

print all_primes(20)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM