tags:

views:

60

answers:

2

Hello. I'm using python, and I have a list of sets, constructed like this:

list = [set([])]*n

...where n is the number of sets I want in the list. I want to add a value to a specific set in the list. Say, the second set. I tried

list[1].add(value)

But this instead adds the value to each set in the list. This behaviour is pretty non-intuitive to me. Through further tests, I think I've found the problem: the list apparently contains 10 instances of the same set, or ten pointers to the same set, or something. Constructing the list through repeated calls of

list.append(set([]))

allowed me to use the syntax above to add elements to single sets. So my question is this: what exactly is going on in my first list-construction technique? It is clear I don't understand the syntax so well. Also, is there a better way to intialize an n-element list? I've been using this syntax for a while and this is my first problem with it.

+4  A: 

You've pretty much summarized the problem yourself -- the X*n syntax makes one instance of X and includes it n times. It's not a problem for things like 'a'*10 because it doesn't matter if every character in that string happens to point to the same 'a', but it does for mutable constructions like lists and sets. You can make n separate sets using a list comprehension:

list = [set() for x in xrange(n)]
Michael Mrozek
Ah, that's the sort of short, sweet, compact statement I enjoy. Thanks a bunch.
Kapelson
Compactness like that is the main reason I like Python :)
Michael Mrozek
Compactness? Sheesh. `list = [set() for x in xrange(n)]`
John Machin
Well, I copied `set([])` from his code :)
Michael Mrozek
A: 

Yes, that is correct. The * syntax is simply copying the reference that many times. Your method works fine, or you can use a list comprehension to construct that many sets as in:

list = [set([]) for x in xrange(n)];
Michael Aaron Safyan