-3

I was practicing python and found the below behaviour and I failed to understand why. Can someone explain why?

Case 1

a = [[] for i in range(5)]
b = [[]] * 5
a[3].append(3)
b[3].append(3)
print(a) # Output: [[], [], [], [3], []]
print(b) # Output: [[3], [3], [3], [3], [3]]

I see different behavior on a and b, what's the difference between a and b?

Case 2

def test(sentences):
    root = {}
    for sentence in sentences:
        base = root
        for word in sentence.split(' '):
            if not base.get(word):
                base[word] = {}
            base = base[word]
    return root

print(test(["Hello world", "Hello there"]))
# Output: {'Hello': {'world': {}, 'there': {}}}

Maybe a noob question but In Case 2 when you're not modifying root how is it getting modified?

Barmar
  • 741,623
  • 53
  • 500
  • 612
Chandan Naik
  • 61
  • 10
  • 1
    `[] * 5` turns into `list.__mul__(5)`. So, the list does the extension. But how could a list know how to create new instances of whatever objects it happens to hold? Instead it just adds references to existing objects. `[[]]*5` is 5 references to a single list. – tdelaney Oct 09 '22 at 23:08
  • 1
    `base = root` means that any modification to `base` also modifies `root`, since both variables refer to the same dictionary. – Barmar Oct 09 '22 at 23:08

1 Answers1

2

* operation on list will be creating duplicates of one list. Here is the proof,

In [1]: a = [[] for i in range(5)]
   ...: b = [[]] * 5

In [2]: [id(i) for i in a]
Out[2]: [4649788160, 4640976128, 4647308224, 4647305856, 4643089472]

In [3]: [id(i) for i in b]
Out[3]: [4648966336, 4648966336, 4648966336, 4648966336, 4648966336]

Same for happening for case2 as well.

Rahul K P
  • 15,740
  • 4
  • 35
  • 52