Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Difference in list output
#1
Between:

tt = [0,1]

a1 = [tt]*4
a2 = [tt for _ in range(4)]
a3 = [[0,1]]*4

a1[0][1] = 6
a2[0][1] = 6
a3[0][1] = 6

print(a1)
print(a2)
print(a3)
Output:
[[0, 6], [0, 6], [0, 6], [0, 6]] [[0, 6], [0, 6], [0, 6], [0, 6]] [[0, 6], [0, 6], [0, 6], [0, 6]]
&:

b1 = [[0,1] for _ in range(4)]

b1[0][1] = 6

print(b1)
Output:
[[0, 6], [0, 1], [0, 1], [0, 1]]
I can't understand this difference in result, can you help me?
Reply
#2
Lists are mutable. So if you reassign one, it doesn't reassign the whole list, it doesn't make a copy of one. You just now have two names pointing to the same list. And if you make a list of lists (if you're not careful), you end up with a list of references to the same list.

So the first two lists you have, a1 and a2, and just a bunch of references to the same list that tt is pointing at. If you change any one of them, that changes the list they are all pointing at. Now you can look at any of them, and they are all pointing at the original list which you changed.

a3 is similar, in that it's one list. The multiplication just makes more references to that same list. It's a different list than tt, but a3 is still four things pointing to the same list.

b1 is different because each time through the loop in the list comprehension, the list is reevaluated. So it is four pointers to four different lists. They are still pointers, though. So if you assigned cc = b[0], and changed cc, b[0] would also reflect those changes.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Thanks a lot Thumbs Up

Okay, so we can say that a1, a2, a3 and b1 have 1 common point: they all build a list of lists.

For a1, a2 & a3, the items that make up their list of lists all point to the original list.

For exemple:
tt = [0,1] 
a1 = [tt]*4
a2 = [tt for _ in range(4)]
a1[0][1] = 6
#Or
a2[0][1] = 6
print(tt)
Output:
[0, 6]
The elements that make up the b1 list of lists all point to themselves in the original list.

For exemple:
b1 = [[0,1] for _ in range(4)]
b1[0][1] = 6
cc = b1[0]
print(cc)
print(b1)
Output:
[0, 6] [[0, 6], [0, 1], [0, 1], [0, 1]]
cc[1] = 2
print(cc)
print(b1)
Output:
[0, 2] [[0, 2], [0, 1], [0, 1], [0, 1]]
tt is assigned by a list. So for a1 & a2 we copy n times (by multilication and iteration) into a list some references of the list tt.

For a3 the sub-list will be assigned in literal form. In a list, some references from this literal list will be simply copied n times (by multiplication) for a result similar to a1 & a2.

For b1 the sub-list will be assigned in literal form and re-evaluated for each copy (by iteration) in a list for n independent copy.

So for a2 =[tt for _ in range(4)], tt is not re-evaluated because it refers to the list assigned to it, unlike b1 = [[0,1] for _ in range(4)].
For a1 & a3 it is a simple copy, from a list assigned for a1 and from a list expressed literally for a3.

Is it correct?
Reply
#4
It's easy to observe what happens:

>>> lst = [0, 1]
>>> first = [lst] * 4
>>> [id(item) for item in first]
[4443423296, 4443423296, 4443423296, 4443423296]       # referencing same object
>>> second = [lst for _ in range(4)]
>>> [id(item) for item in second]
[4443423296, 4443423296, 4443423296, 4443423296]       # referencing same object
>>> third = [[0, 1] for _ in range(4)]
>>> [id(item) for item in third]
[4443415872, 4442844672, 4443418112, 4443422912]       # referencing different objects
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#5
Well, I do not want to observe, I want to understand the process by reading the code without having to do tests.
And I'm talking about list of lists.
Reply
#6
By observing you can understand. The id() function perfringo is using shows the address of the item in question. So he is showing that in the first two instances, it's all residing in the same memory address: it's all pointing to the same list. In his last example, there are four different addresses, indicating four different lists.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#7
Of course, and not only I can understand but especially I can learn.

Your help to both was relevant and clear, thank you for your concern. Clap

But in my answer (#3) I try to explain the reading of the code, when I read or write it, from a semantic point of view.
To make the difference, for example, between [tt for _ in range(4)] and [[0,1] for _ in range(4)] which gives different results.

I try to explain it as follows: in both cases we create a list of lists by iteration [... for _ in range(4)].
In the case with tt, the copied list is a variable that contains a list, which is why tt is not re-evaluated at each iteration, because it refers to the list that has been assigned to it and will give n copy with the same reference.
In the other ([0,1]) it is the literal expression of a list that contains two elements, this is the reason why [0,1] is re-evaluated at each iteration and which will give n independent copy therefore with different references.

In reading or writing the code the difference to be identified between [tt for _ in range(4)] and [[0,1] for _ in range(4)] is tt & [0,1], variable against literal form in list of lists creation by itération.
And of course we cannot identify this differences if we have not understood it and observed it.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  difference between forms of input a list to function akbarza 6 929 Feb-21-2024, 08:02 PM
Last Post: bterwijn
  Output difference from 2 lists of different sizes with words gracenz 5 1,242 Sep-02-2022, 05:09 PM
Last Post: Larz60+
  set.difference of two list gives empty result wardancer84 4 1,434 Jun-14-2022, 01:36 PM
Last Post: wardancer84
  sum() list from SQLAlchemy output Personne 5 4,346 May-17-2022, 12:25 AM
Last Post: Personne
  What is the difference between a generator and a list comprehension? Pedroski55 2 2,177 Jan-02-2021, 04:24 AM
Last Post: Pedroski55
  How to append to list a function output? rama27 5 6,649 Aug-24-2020, 10:53 AM
Last Post: DeaD_EyE
  json.dumps list output qurr 12 5,076 Apr-08-2020, 10:13 PM
Last Post: micseydel
  If item in list = true, Output = xx kroh 0 1,458 Feb-19-2020, 09:17 AM
Last Post: kroh
  output list reducing each time through loop 3Pinter 6 3,447 Mar-19-2019, 01:31 PM
Last Post: perfringo
  os.popen output to a list .. evilcode1 1 5,270 Oct-02-2018, 08:42 PM
Last Post: ODIS

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020