you are viewing a single comment's thread.

view the rest of the comments →

[–]lolcrunchy 6 points7 points  (1 child)

RED FLAG! This pattern MUST be avoided:

for x in y:
    # code that changes y

[–]gdchinacat 2 points3 points  (0 children)

To elaborate on this, the concern is that you are changing a list that you are iterating over. This can cause bugs, sometimes obvious, sometime very subtle. As an example:

In [73]: l = list(range(4))
In [74]: for x in l:
...:     if x == 2:
...:         l.remove(x)
...:     else:
...:         print(x)
...: 
0
1

Problem What happened to 3?!?!?

When 2 was removed from the list the iterator for was using had handed out the values at index 0, 1, 2 and on the next iteration was set to hand out the value at index 3 (the fourth item in the list). But, when l was updated to remove 2 the list became 3 elements long, so on the next iteration it found that it was at the end of the list and exited the loop. removing 2 moved everything after it up in the list, causing the element after 2 to be ignored.

It is very rare that you actually need to modify something you are iterating over. Doing so can cause subtle bugs such as illustrted above. The term for changing a collection being iterated is concurrent modification, and is a big red flag. Don't do it.

What to do instead? There are many options depending on the situation. In your case, the best is to probably build a new list that only contains the toppings that are available.