tsaxi
tsaxi

Reputation: 13

Cannot change content of list within list. Can anybody explain why?

I have a month variable which is a list of lists of tuples. Each list represents a week and each day is a tuple of the day of the month and the week day. I wish to make my month a list of lists of month days. I tried to do it like this:

for week in month:
    week = [day[0] for day in week]

for [[(1, 1), (2, 2)], [(3, 3), (4, 4)]] I expect to get [[1, 2], [3, 4]], but the list doesn't change. To my understanding of python my code is perfectly fine, so what am I missing? Isn't week a reference to each week in the month?

Upvotes: 1

Views: 449

Answers (4)

viraptor
viraptor

Reputation: 34205

By assigning something to week, you change what the variable is bound to, not what the list contains. To do what you want to do without many changes, do:

for week in month:
    week[:] = [day[0] for day in week]

It will assign the result to a specified range inside week - in this case, the whole range, replacing all existing elements.

Upvotes: 2

tauran
tauran

Reputation: 8036

Why not just:

>>> foo = []
>>> for week in month:
...     foo.append([day[0] for day in week])
... 
>>> foo
[[1, 2], [3, 4]]

Simple to read, simple to understand, ...

Upvotes: 0

kennytm
kennytm

Reputation: 523784

No, the variable you are iterating on is never a "reference" (as in C++'s reference).

You should understand the for loop as

month_iter = iter(month)
try:
  while True:
    week = next(month_iter)
    # here begins your code
    week = [day[0] for day in week]
    # here ends your code
except StopIteration:
  pass

Clearly, the 2nd assignment won't affect the content of month.

You could just write

month = [[day[0] for day in week] for week in month]

to replace the whole month list, or use enumerate as stated in @Ivo's answer.

Upvotes: 2

Ivo van der Wijk
Ivo van der Wijk

Reputation: 16795

Assignment in python is merely attaching a name to an object, it's not an operation on the object itself (but do not confuse this with getting/setting attributes on an object)

if you have

x = [1,2,3]
y = x[1]

Then y will simply be 2 and lose all reference to the list it came from. Changing y will not change x. To do so, index x properly.

In your case, you want to iterate over the indexes of month and assign to the appropriate entry

for index, week in enumerate(month):
    month[index] = [day[0] for day in week]

Upvotes: 1

Related Questions