2

I have tried to create a list of whole numbers under 1000 (aka, 0 to 999), then delete the numbers that don't comply with a certain rule [ex. must be divisible by 7 or 3]. After, I have find the sum of all these numbers. Below is the code I wrote to do so.

number_list = []

for x in range(1000):
number_list.append(x)

index = 0
element = number_list[index]

max = 1000
deleted = 0

while index < max - deleted:

    element = number_list[index]

    if element % 7 != 0 or element % 3 != 0:
        number_list.remove(element)
        deleted = deleted + 1

    index = index + 1

print(sum(number_list))

This runs without any issues, but it does not return the correct sum. The correct sum is 214216, but this gives me 261832 instead, leading me to believe that more than 40 elements that should have been deleted, have not been deleted.

How can I fix this problem?

  • 1
    The list comprehension is probably the right way to go about it, but, in general, if you ever want to iterate through a list while deleting things, go backwards. – NightShadeQueen Jun 28 '15 at 01:58

4 Answers4

3

This is one way to do it using list comprehensions:

number_list = [i for i in range(1000) if not i % 7 != 0 or not i % 3 != 0 ]
print sum(number_list) #Python2

Output:

214216
Joe T. Boka
  • 6,554
  • 6
  • 29
  • 48
2

Using list comprehension should be simpler for this problem. Anyway, I'll try to fix your implementation.

  • The condition element % 7 != 0 or element % 3 != 0 should be and instead of or.
  • If a number is deleted in the loop iteration, index shouldn't move to the next, because the next element is at this index now.

In summary:

if element % 7 != 0 or element % 3 != 0:
    number_list.remove(element)
    deleted = deleted + 1

index = index + 1

should be:

if element % 7 != 0 and element % 3 != 0:
    number_list.remove(element)
    deleted = deleted + 1
else:
    index = index + 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
2

When you remove elements from the list: number_list.remove(element), the meaning of the index changes so that on the next iteration, after incrementing index, element = number_list[index] now references a value other than the index-th item of the original number_list. Thus, some values in the original number_list are never checked.

The solution, in general, is to not mutate a list while iterating over it. Instead, use a list comprehension (or, for memory-efficiency, a generator expression) to build a new list:

In [107]: sum([i for i in range(1000) if (i % 7 == 0) or (i % 3 == 0)])
Out[107]: 214216

or, iterate over index backwards, counting from 999 down to 0, so that removing the index-th item will not affect the indexing of other items when using a smaller index.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
0

Everything is much simpler.

sum=0
for x in range(1000):
    if x % 7 == 0 or x % 3 == 0:
        sum=sum+x
print sum

Result:

214216
Alex Ivanov
  • 695
  • 4
  • 6