'What is the difference between using the * operator to create a list and for _ in range? [duplicate]
list1 = [set(), set(), set()]
list2 = [set() for _ in range(3)]
print(list1 == list2) results in true
However, they seem to differ.
I was solving this problem: https://leetcode.com/problems/valid-sudoku/
Using the following does not work:
rows = [set()] * 9
cols = [set()] * 9
boxes = [set()] * 9
But replacing that with:
rows = [set() for _ in range(9)]
cols = [set() for _ in range(9)]
boxes = [set() for _ in range(9)]
makes the code work. I'm very confused as to what the difference is and how there could even be a difference if they are equal.
Solution 1:[1]
When you use [set()]*9 you create a list with 9 references to the same set object, when you use [set() for _ in range(9)] you create a list with 9 unique set objects. For example, if you run the following:
r1 = [set()]*3
r2 = [set() for _ in range(3)]
print(r1 == r2)
r1[0].add(1)
r2[0].add(1)
print(r1)
print(r2)
print(r1 == r2)
it will print
True
[{1}, {1}, {1}]
[{1}, set(), set()]
False
You can see that modifying r1[0] modified all three entries in the list since they all refer to the same set object, but modifying r2[0] only modified one of the list entries since they are all unique set objects.
The first equality check is True (like you saw in your test) because the lists are both filled with empty sets, regardless of whether any of them refer to the same object or not. The second check is false because the sets no longer have the same contents between the two lists.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tyler V |
