0

Consider this example:

In [44]: exl_set = set(a.node)
In [45]: exl_set 
Out[45]: set(['1456030', '-9221969'])
In [46]: exl_set.add(b.node)
In [47]: exl_set
Out[47]: set(['1456030', ('-9227619', '1458170'), '-9221969'])

What is the best way to add tuples of length 2 to a set without breaking them apart with the first add? The result should look like this:

Out[48]: set([ ('-9221969','1456030'),('-9227619', '1458170')])
LarsVegas
  • 6,522
  • 10
  • 43
  • 67

3 Answers3

4

Wrap your initial node in list or tuple:

exl_set = set([a.node])

to not have it interpreted as a sequence of values.

The set() constructor interprets the argument as an iterable and will take all values in that iterable to add to the set; from the documentation:

class set([iterable]):
Return a new set or frozenset object whose elements are taken from iterable.

Demo:

>>> node = ('1456030', '-9221969')
>>> set(node)
set(['1456030', '-9221969'])
>>> set([node])
set([('1456030', '-9221969')])
>>> len(set([node]))
1

Alternatively, create an empty set and use set.add() exclusively:

exl_set = set()
exl_set.add(a.node)
exl_set.add(b.node)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks! Well, of course I thought about this. But it means I have to keep track of my iteration. Thought there might be a better way to go... – LarsVegas Oct 24 '13 at 10:12
  • The last piece of information is what I was looking for! Great, thanks! – LarsVegas Oct 24 '13 at 10:16
  • Glad to have been of help! – Martijn Pieters Oct 24 '13 at 11:46
  • @LarsVegas: out-of-band comment: the Careers URL on your profile is a private edit URL for your profile, visible to you only. You want to use the [public URL for your profile](http://meta.stackexchange.com/a/199672) instead. – Martijn Pieters Oct 24 '13 at 11:48
  • 1
    btw, if you have a choice between creating a list, or a tuple - choose the tuple i.e. instead of `set([node])`, use `set((node))`. it's about 25% faster - 231 ns vs. 304 ns for this particular case, per addition. – Corley Brigman Oct 24 '13 at 13:18
1

When you initialize the set, the argument is treated as an iterable, not as a single item. You can do it like that:

    >>>node = (1, 3)
    >>>node_set = set([node,]) #  initialize a set with a single ilement
    >>>node_set
    set([(1, 3)])

or alternatively:

    >>>node = (1, 4)
    >>>node_set = set()  # initialize an empty set
    >>>node_set.add(node)  # add a single element
    >>>node_set
    set([(1, 4)])
Alexander Zhukov
  • 4,357
  • 1
  • 20
  • 31
1

To update this answer for other time travellers, another method is to use a set literal, which saves on the unnecessary wrap/unwrap process of the previous answers:

node = (1, 2)
n_set = {node}
n_set

Out[17]: {(1, 2)}

logan
  • 430
  • 5
  • 11