loop through numbers and evaluate if numbers are divisible by certain numbers

两盒软妹~` 提交于 2021-02-10 13:27:10

问题


i wrote a program to evaluate what numbers in a certain range are divisble by only certain numbers (in the range 1 to 9). So far the code seems to work but i tested the steps it takes through at pythontutor http://www.pythontutor.com/visualize.html#mode=edit and something odd happened.

In the second loop, the code doesnt always check all values (k) for its divisibility but sometimes leaves out the last value (k). Better to give you an example:

Liste = []
for i in range (1500, 1700):
    if i%5 == 0 and i%7 == 0:
        Liste.append(i)
print (Liste)

Teiler = [2, 3, 4, 6, 8, 9]
for k in Liste:
    z = 0
    for w in range (len(Teiler)):
        if k%Teiler[z] == 0:
            Liste.remove(k)
            z += 1
            break
        else:
            z += 1

print (Liste)

Here the output is as follows:

[1505, 1540, 1575, 1610, 1645, 1680]

[1505, 1575, 1645]

And its the output that its supposed to be, as in the second list are only the numbers divisible by 5 and 7. Also on pythontutor the second for loop goes through all values (k).

But when i change the range of number like the following (line 2, change range from 1700 to 1800):

Liste = []
for i in range (1500, 1800):
    if i%5 == 0 and i%7 == 0:
        Liste.append(i)
print (Liste)

Teiler = [2, 3, 4, 6, 8, 9]
for k in Liste:
    z = 0
    for w in range (len(Teiler)):
        if k%Teiler[z] == 0:
            Liste.remove(k)
            z += 1
            break
        else:
            z += 1

print (Liste)

the output is as the following:

[1505, 1540, 1575, 1610, 1645, 1680, 1715, 1750, 1785]

[1505, 1575, 1645, 1715, 1785]

If i run this code on pythontutor, the code stops at k = 1750 and doesnt check for k = 1785.

Why is it behaving that way? Is it a problem with the check on pythontutor? Or is there a problem with my code?

I want to understand why Python is doing what it does.

Thank you very much for your help. Iam sorry if this is a noob question or iam missing out something obvious.


回答1:


Don't remove items from the list you iterate over, as the other answer states. Changing the length of the list affects the iteration. Example:

>>> L=list(range(10))
>>> for i in L:
...   if i==5: L.remove(i)
...   print(i)
...
0
1
2
3
4
5  # removed 5, and skipped 6!
7
8
9

Also w is never used, although z is the equivalent. Instead, iterate directly over Teiler and add items to a new list if it satisfies your condition:

Liste = []
for i in range (1500, 1800):
    if i%5 == 0 and i%7 == 0:
        Liste.append(i)
print (Liste)

Liste2 = []
Teiler = [2, 3, 4, 6, 8, 9]
for k in Liste:
    for w in Teiler:
        if k % w == 0:
            break
    else:
        Liste2.append(k)

print(Liste2)

Output:

[1505, 1645, 1715]

If you haven't seen for/else, the else only executes if you don't break from the for loop, so all of k % w != 0 has to be true.

Another option is to use list comprehensions, which really simplify the code:

L = [i for i in range(1500,1800) if i%5 == 0 and i%7 == 0]
L = [x for x in L if all(x % k != 0 for k in (2,3,4,6,8,9))]
print(L)

Output:

[1505, 1645, 1715]

Note 1575 and 1785 are divisible by 3, so both your sample lists had errors from removing values in the list.




回答2:


Your problem is in this line:

Liste.remove(k)

because you are removing element from the same list that you use for the for loop so when you delete an element the list is going to be shorter but next iteration you will jump an element.

I advice to use two list or use a while loop and when you remove the element from list you don't go to next iteration and you decrease the len of the list of 1; example:

Liste = []
for i in range (1500, 1800):
    if i%5 == 0 and i%7 == 0:
        Liste.append(i)
print (Liste)

Teiler = [2, 3, 4, 6, 8, 9]

l=len(Liste)
i=0
while i<l:
    k=Liste[i]
    z = 0
    for w in range (len(Teiler)):
        if k%Teiler[z] == 0:
            Liste.remove(k)
            l-=1
            i-=1
            z += 1
            break
        else:
            z += 1
    i+=1

This code could be improved but was for let you understand how you can do it



来源:https://stackoverflow.com/questions/53064481/loop-through-numbers-and-evaluate-if-numbers-are-divisible-by-certain-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!