0

Example says it all:

x = [set()]*5
x[0].add(1)
print x

yields:

[set([1]), set([1]), set([1]), set([1]), set([1])]

I understand what happened, but is this expected? Do I really need to use a loop to initialize a list with empty sets that are not aliases of each other?

Matyas
  • 644
  • 6
  • 15
  • Whether that's expected depends on who is expecting. Some people do, some people don't. Strange question. – Stefan Pochmann Aug 14 '16 at 18:48
  • What is strange about: "Do I really need to use a loop to initialize a list with empty sets that are not aliases of each other?" – Matyas Aug 14 '16 at 18:59
  • If someone also answers the second question with just Yes or No, that poster will get the vote. – Matyas Aug 14 '16 at 19:00
  • Thank Karin. The question linked is also a duplicate which directs to another duplicate... This seems to be a common issue I gather. I traced it to: http://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across-sublists-unexpectedly as the first question of which all are duplicates. I still have a second question open: Can this be done without loops? – Matyas Aug 14 '16 at 19:04
  • Yes, you need to use a loop, eg `x = [set() for _ in range(5)]`; your code creates a list of 5 references to the one `set` object. Or you could do it without a loop: `x=[set(), set(), set(), set(), set()]` :) – PM 2Ring Aug 14 '16 at 19:05

1 Answers1

1

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.

Daniel
  • 2,345
  • 4
  • 19
  • 36