3

I am trying to create a list inside another list in Python. I noticed that depending on the declaration the final (outer) list behaves differently.

I tried to create list of lists in two different ways. Both cases gave me varies results.

#Case 1
def test():
    lt1 = lt2 = list()
    for i in range(0, 10):
        for j in range(0, 2):
            lt1.append(j);
        lt2.append(lt1);
        lt1 = [];
    print (lt2)

if __name__ == "__main__":
    test()
#Case 2
def test():
    lt1 = list()
    lt2 = list()
    for i in range(0, 10):
        for j in range(0, 2):
            lt1.append(j);
        lt2.append(lt1);
        lt1 = [];
    print (lt2)

if __name__ == "__main__":
    test()

In case 1 the output is [0, 1, [...], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]]

In case 2 the output is [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 1]] which is the expected answer for my implementation.

I wanted to know why the first code snippet acts differently.

deb17dj
  • 33
  • 3
  • 2
    Possible duplicate of [Reference vs Assignment in Python mutable objects](https://stackoverflow.com/questions/21092937/reference-vs-assignment-in-python-mutable-objects) – Devesh Kumar Singh May 20 '19 at 08:46
  • 5
    In Case1, `lt1 = lt2 = list()`, `lt1` and `lt2` point to the same list, so modifying one modifies the other, which doesn't hold true in Case 2 – Devesh Kumar Singh May 20 '19 at 08:47
  • The two line equivalent of `lt1 = lt2 = list()` is actually `lt1 = list()`, `lt2 = lt1`. i.e. `lt2` is just a reference to the same list `lt1` refers to. I think the take away here should be don't use multiple assignments in 1 line. – Dan May 20 '19 at 08:54

1 Answers1

2

It's because of the first line:

>>> a = b = []
>>> a
[]
>>> b
[]
>>> a is b
True
>>> a = []
>>> b = []
>>> a is b
False
>>> 

With one line as in case 1, it contains the same object, so:

>>> a = b = []
>>> a.append(1)
>>> a
[1]
>>> b
[1]
>>> 

Which doesn't happen with two lines:

>>> a = []
>>> b = []
>>> a.append(1)
>>> a
[1]
>>> b
[]
>>> 

So simply because the first line of case 1 has a and b that are the exact same objects, unlike the second case's fist line, that are same values, but different id (id(a) == id(b) is the same as a is b).

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
  • 1
    @deb17dj See: https://stackoverflow.com/questions/13851581/python-printed-a-list-three-dots-appeared-inside-sublists – U13-Forward May 20 '19 at 09:08
  • Thanks. That answers part of my question. My doubt now is what is the [...] and what causes it? >>> a = b = list() >>> a [] >>> b [] >>> a is b True >>> b.append(0) >>> b.append(1) >>> a [0, 1] >>> b [0, 1] >>> a.append(b) >>> a [0, 1, [...]] >>> b [0, 1, [...]] – deb17dj May 20 '19 at 09:10
  • @deb17dj Read my link above, it's well explained. – U13-Forward May 20 '19 at 09:10
  • @deb17dj Happy to help :-) – U13-Forward May 20 '19 at 09:12