Example says it all:
x = [set()]*5
[set(), set(), set(), set(), set()]
I understand what happened, but is this expected?
This behavior is expected in Python. Using the
* operator in this context creates references to the
set() objects, which means that when you change one such object (like you did with your
add()), you change all of the references to that object.
Do I really need to use a loop to initialize a list with empty sets that are not aliases of each other?
Yes; this is the proper way to create separately-referenced objects.