Convert a list to a set of element order changes

I recently noticed that when converting a list to set order of the elements is changed and sorted by characters.

Consider this example:

 x=[1,2,20,6,210] print x # [1, 2, 20, 6, 210] # the order is same as initial order set(x) # set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted 

My questions -

  1. Why is this happening?
  2. How can I perform operations with sets (especially Set Difference) without losing their original order?
+83
python set
Mar 20 '12 at 18:19
source share
9 answers
  • A set is an unordered data structure.

  • Do not use set , but collections.OrderedDict :

     >>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210]) >>> b = collections.OrderedDict.fromkeys([6, 20, 1]) >>> collections.OrderedDict.fromkeys(x for x in a if x not in b) OrderedDict([(2, None), (210, None)]) 

    Note that the order of b does not matter, so it can be any iterable, but it must be iterable that supports O (1) membership tests.

Change The answer above assumes that you want to perform (ordered) given operations in all the collections encountered, in particular, also as a result of the previous given operation. If this is not necessary, you can simply use lists for some collections and set for others, for example.

 >>> a = [1, 2, 20, 6, 210] >>> b = set([6, 20, 1]) >>> [x for x in a if x not in b] [2, 210] 

This loses order b , and does not allow you to quickly check membership on a and the result. Kits allow you to quickly verify membership, and lists keep order. If you need both of these functions in the same collection, use collections.OrderedDict .

+82
Mar 20 '12 at 18:21
source share

In Python 3.6, set() should now be in order, but there is another solution for Python 2 and 3:

 >>> x = [1, 2, 20, 6, 210] >>> sorted(set(x), key=x.index) [1, 2, 20, 6, 210] 
+34
Dec 29 '16 at 11:41
source share

Answering your first question, a set is a data structure optimized for operations on sets. Like a mathematical set, it does not provide or does not support any particular order of elements. The abstract set concept does not provide order, so implementation is optional. When you create a set from a list, Python has the right to reorder the elements for the needs of the internal implementation, which it uses for a set that is able to efficiently perform operations on sets.

+14
Mar 20 2018-12-18T00:
source share

As indicated in other answers, sets are data structures (and mathematical concepts) that do not preserve the order of elements -

However, using a combination of sets and dictionaries, it is possible that you can achieve what you want, try using these snippets:

 # save the element order in a dict: x_dict = dict(x,y for y, x in enumerate(my_list) ) x_set = set(my_list) #perform desired set operations ... #retrieve ordered list from the set: new_list = [None] * len(new_set) for element in new_set: new_list[x_dict[element]] = element 
+3
Mar 20 '12 at 19:23
source share

Based on Sven's answer, I found that I used collections. This way helped me accomplish what you want and let me add more elements to the dict:

 import collections x=[1,2,20,6,210] z=collections.OrderedDict.fromkeys(x) z OrderedDict([(1, None), (2, None), (20, None), (6, None), (210, None)]) 

If you want to add elements, but still treat them as a set, which you can simply do:

 z['nextitem']=None 

And you can perform an operation like z.keys () on a dict and get a set:

 z.keys() [1, 2, 20, 6, 210] 
+1
Jan 30 '15 at 19:43
source share

Implementation of the concept of the highest score given above, which returns it to the list:

 def SetOfListInOrder(incominglist): from collections import OrderedDict outtemp = OrderedDict() for item in incominglist: outtemp[item] = None return(list(outtemp)) 

Tested (briefly) on Python 3.6 and Python 2.7.

+1
May 01 '18 at 12:57
source share

In case you have a small number of elements in your two initial lists for which you want to perform the operation of setting differences instead of using collections.OrderedDict which complicates the implementation and makes it less readable, you can use:

 # initial lists on which you want to do set difference >>> nums = [1,2,2,3,3,4,4,5] >>> evens = [2,4,4,6] >>> evens_set = set(evens) >>> result = [] >>> for n in nums: ... if not n in evens_set and not n in result: ... result.append(n) ... >>> result [1, 3, 5] 

Its temporal complexity is not so good, but it is neat and easy to read.

0
May 22 '19 at 9:42
source share

This is because a set is an unordered data structure.

To maintain order, you can do this as follows:

 x=[1,2,3,20,6,210,50,20]; print(sorted(set(x),key=x.index)); 

As you will see, you can perform operations on sets without losing their original order.

0
Aug 29 '19 at 3:30
source share

Here is an easy way to do this:

 x=[1,2,20,6,210] print sorted(set(x)) 
-8
Jul 07 '16 at 16:04
source share



All Articles