0

In Python, is it possible to copy a set in the same order as the original? For example, rather than:

>>> s = {'r','g','b'}
>>> t = {i for i in s}
>>> t
set(['r', 'b', 'g'])
>>> 

Can t be set to:

{'r','g','b'}
  • Why don't you use a list then? – thefourtheye Mar 16 '14 at 16:56
  • 2
    No. Sets aren't ordered. If you want order you need another data structure - a `list` or and `OrderedSet`. – rlms Mar 16 '14 at 16:56
  • @thefourtheye: I don't want duplicates. –  Mar 16 '14 at 16:57
  • @sweeneyrod Yes, I saw that. Just wondering if there might be an easy way to make a copy. –  Mar 16 '14 at 17:01
  • 3
    @gjdanis Sets *have no order*, so you can’t *copy* the original order simply because there wasn’t an order to begin with. – poke Mar 16 '14 at 17:04
  • @poke That's true--and so weird! When you make a set, then, how is the position of the elements in the set determined? –  Mar 16 '14 at 17:07
  • @gjdanis They don’t have a position. When you print it, it just returns the elements in an arbitrary order that has no further meaning but is entirely implementation specific. Imagine a bag with items, and you simply draw elements one-by-one from it and that’s the order for sets. It’s non-predicatable, without any meaning and solely for the purpose of accessing all elements. – poke Mar 16 '14 at 17:09
  • @poke Is there a reason the designers of Python decided to do things this way? I thought the main advantage (among others) of using a `set` over a `list` was to avoid duplicates? –  Mar 16 '14 at 17:11
  • 1
    @gjdanis But [sets](http://en.wikipedia.org/wiki/Set_%28mathematics%29) simply don’t have an order. – poke Mar 16 '14 at 17:14
  • @poke Yes, but is there an advantage to not ordering? –  Mar 16 '14 at 17:14
  • 3
    @gjdanis Several. Most and foremost, it’s way more efficient. If you have an order, then *that* order is part of the item’s property, making it harder to identify items with the same value (but different positions). Sets are implemented using hash tables, so they have a O(1) access; lists cannot work that and have a O(N) access instead. If there was a data structure that would support everything (efficient access, uniqueness, order) then that would be incredible cool, but it’s simply not possible; so you have to decide what you need and what you can pass on. – poke Mar 16 '14 at 17:19
  • @poke Couldn't you allow O(1) access for a list? Isn't appending and popping the last element off the list O(1)? https://wiki.python.org/moin/TimeComplexity –  Mar 16 '14 at 17:52
  • @gjdanis List access by index is constant time; but getting an item by value or checking if a value exists within the list (which would be required if you want to allow only distinct elements) is linear time as you need to check every element. Btw. if you have further questions or want to discuss this more, please join [chat](http://chat.stackoverflow.com/rooms/6/python) and let us continue there. – poke Mar 16 '14 at 18:05

1 Answers1

1

Try manipulating the OrderedDict from collections, see http://docs.python.org/2/library/collections.html#collections.OrderedDict.

>>> from collections import OrderedDict
>>> x = ['a','b','c','b','c']
>>> list(OrderedDict.fromkeys(x))
['a', 'b', 'c']
alvas
  • 115,346
  • 109
  • 446
  • 738