2

I have a list that needs to contain a variable number of independent sets. When I run the following piece of code, I want to add the string "testing" to only the first set.

numberOfSets = 3    
test = [set()]*numberOfSets
test[0].add("testing")
print test

However, when I print test, it shows three identical sets that all contain testing. How can I set up my list so I can separately access each set?

fdsa
  • 1,379
  • 1
  • 12
  • 27

2 Answers2

4

You can do

test = [set() for _ in xrange(numberOfSets)]  # use 'range' in Python 3.x

[set()]*x creates a list with x of the same set instance, whereas the comprehension above creates a new, independent set on each iteration, as desired.

In general, you should be very cautious whenever you multiply lists whose elements are mutable.

arshajii
  • 127,459
  • 24
  • 238
  • 287
  • Thank you for the information. I'm using Python 2.7 so I will accept the other answer. – fdsa Jul 27 '13 at 23:30
  • Just curious, why should I be careful multiplying lists whose elements are mutable? – fdsa Jul 27 '13 at 23:30
  • @fdsa `xrange` is better for 2.7, as shown above. I meant you should use `range` in 3.x. – arshajii Jul 27 '13 at 23:31
  • @fdsa `xrange()` creates an iterator, while `range()` just creates the list. If you're interested for performance in 2.7, then `xrange` is the way to go. However, in Python 3, `xrange()` was removed, and `range` took on the same capabilities as `xrange` did in 2.7 – TerryA Jul 27 '13 at 23:33
  • You want to be careful for exactly the reason you describe: mutating one element of the multiplied list can effect other elements. With immutable list elements, you never need to worry about this. – arshajii Jul 27 '13 at 23:33
4

When you do [set()]*3, you create three sets that reference the same object, thus when you change one value, the others change. Use a list comprehension here instead:

>>> numberOfSets = 3   
>>> test = [set() for _ in xrange(numberOfSets)]
>>> test[0].add("testing")
>>> print test
[set(['testing']), set([]), set([])]
TerryA
  • 58,805
  • 11
  • 114
  • 143