4

I am looping through a list of tuples and, each iteration, I am appending some extra elements to the current loop variable, then performing an action with the new list.

The temptation is to modify the loop variable to include the extra elements, then do something with it.

Consider the following code snippet:

required_part = (0, 4)
optional_part = [(1, 2), (1, 3), (2,3)]

for x in optional_part:
    x += required_part
    x = sorted(x)
    print(x)

But something about mutating the loop variable during a loop makes me feel uneasy.

Are there any situations when mutating the loop variable will produce unexpected results or can I just stop worrying?

Note: there seems to be plenty of discussion about mutating the iterable. This question is rather about mutating the loop variable

5
  • 3
    this is perfectly OK, you're reassigning x. That doesn't change optional_part list, of course. Commented Sep 29, 2017 at 12:01
  • You're just re-assigning x, and at the start of each iteration x is re-assigned to the next value in the loop. There's not mutation/modification involved (tuples are immutable anyway) Commented Sep 29, 2017 at 12:05
  • Knowing how to formulate this question is why I asked this other question. Preparation! Commented Sep 29, 2017 at 12:06
  • Never worry about mutating tuples :) Python won't let you Commented Sep 29, 2017 at 12:07
  • @schwobaseggl Yes, I did think about this. Maybe I should've made the example elements lists instead of tuples. But I thought maybe people would say "just use tuples" or something so I left it as it was. Commented Sep 29, 2017 at 12:10

3 Answers 3

4

As long as you're not changing the collection itself, it doesn't matter. The problem only arises when you try to add/delete from the very collection, you're iterating over.

# Say something like this

for x in optional_part:
    optional_part.remove(x)
Sign up to request clarification or add additional context in comments.

3 Comments

And even then, it's a perfectly normal thing to modify the collection too; for e.g. looping while a collection is non-empty and popping elements as you go, and many other examples.
@AlexanderReynolds however, the code I mentioned wouldn't behave as expected, because of the same. It is fine in case of while loops, but not iteration.
Indeed, I just meant to address OP's worry about modifying variables and collections...both are used normally in programming, but just make sure it's a sensible thing to do.
3

While most has been said in the comments and the other answer, it might be worth noting that the += operator does not always perform a reassignment. It is just the way tuple implements it (which it has to due its immutability). Tuples and lists implement it rather differently:

Lists do mutate:

a = x = [5, 6]
a += [7]
a
# [5, 6, 7]
x
# [5, 6, 7]

Tuples don't:

a = x = (5, 6)
a += (7,)
a
# (5, 6, 7)
x
# (5, 6)

4 Comments

it's not an implementation difference, tuple is immutable: using += changes its reference or it would break guaranteed immutability. At this point ids of a and x differ (like strings)
@Jean-FrançoisFabre list could still impement the __radd__ differently. You have append and extend after all. Also, I think, many have the illusion that a += b is equivalent to a = a + b which is not the case for lists, which I find noteworthy.
Yes, but it would be a bad thing to implement them differenly because of the quadratic complexity of the data copy.
@Jean-FrançoisFabre Quadratic, i'm not sure. For m += n the time complexity should be O(N) in the current implementation and O(M+N) if there was a reassignment with new object, right?
2

The question is, what is the loop variable bound to? If that value is mutable, you can change the contents of the list, though not the list itself.

>>> lst = [[1, 2], [3, 4]]
>>> for x in lst:
...  x += [5]
...
>>> print lst
[[1, 2, 5], [3, 4, 5]]

lst is still the same list of two elements, both those elements have been changed.

If the elements aren't mutable, then nothing changes.

>>> lst = [1,2,3]
>>> for x in lst:
...   x += 5
...
>>> print lst
[1, 2, 3]

1 Comment

Yes of course! The mutability of the elements is the crucial part of this. I knew there was a reason to be nervous!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.