Question

aList = [2, 1, 4, 3, 5]

aList.sort()

=[1, 2, 3, 4, 5]

del aList[2]

=[1, 2, 4, 5]

**unsort the list back to original sequence with '3' deleted**

=[2, 1, 4, 5]

In reality I have a list of tuples that contain (Price, Quantity, Total). I want to sort the list, allow the user to delete items in the list and then put it back in the original order minus the deleted items.

One thing to note is that the values in the tuples can repeat in the list, such as:

aList = [(4.55, 10, 45.5), (4.55, 10, 45.5), (1.99, 3, 5.97), (1.99, 1, 1.99)]
Was it helpful?

Solution 3

You can't really do an "unsort", the best you can do is:

aList = [2, 1, 4, 3, 5]

aList.remove(sorted(aList)[2])

>>> print aList
[2, 1, 4, 5]

OTHER TIPS

You cannot unsort the list but you could keep the original unsorted index to restore positions.

E.g.

from operator import itemgetter

aList = [(4.55, 10, 45.5), (4.55, 10, 45.5), (1.99, 3, 5.97), (1.99, 1, 1.99)]

# In keyList:
# * every element has a unique id (it also saves the original position in aList)
# * list is sorted by some criteria specific to your records
keyList = sorted(enumerate(aList), key = itemgetter(1))

# User want to delete item 1
for i, (key, record) in enumerate(keyList):
    if key == 1:
        del keyList[i]
        break

# "Unsort" the list
theList = sorted(keyList, key = itemgetter(0))

# We don't need the unique id anymore
result = [record for key, record in theList]

As you can see this works with duplicate values.

Unsorting can be done

This approach is like others - the idea is to keep the original indices to restore the positions. I wanted to add a clearer example on how this is done.

In the example below, we keep track of the original positions of the items in a by associating them with their list index.

>>> a = [4, 3, 2, 1]
>>> b = [(a[i], i) for i in range(len(a))]
>>> b
[(4, 0), (3, 1), (2, 2), (1, 3)]

b serves as a mapping between the list values and their indices in the unsorted list.

Now we can sort b. Below, each item of b is sorted by the first tuple member, which is the corresponding value in the original list.

>>> c = sorted(b)
>>> c
[(1, 3), (2, 2), (3, 1), (4, 0)]

There it is... sorted.

Going back to the original order requires another sort, except using the second tuple item as the key.

>>> d = sorted(c, key=lambda t: t[1])
>>> d
[(4, 0), (3, 1), (2, 2), (1, 3)]
>>> 
>>> d == b
True

And now it's back in its original order.

One use for this could be to transform a list of non sequential values into their ordinal values while maintaining the list order. For instance, a sequence like [1034 343 5 72 8997] could be transformed to [3, 2, 0, 1, 4].

>>> # Example for converting a list of non-contiguous
>>> # values in a list into their relative ordinal values.
>>>
>>> def ordinalize(a):
...     idxs = list(range(len(a)))
...     b = [(a[i], i) for i in idxs]
...     b.sort()
...     c = [(*b[i], i) for i in idxs]
...     c.sort(key=lambda item: item[1])
...     return [c[i][2] for i in idxs]
...     
>>> ordinalize([58, 42, 37, 25, 10])
[4, 3, 2, 1, 0]

Same operation

>>> def ordinalize(a):
...     idxs = range(len(a))
...     a = sorted((a[i], i) for i in idxs)
...     a = sorted(((*a[i], i) for i in idxs),
...                key=lambda item: item[1])
...     return [a[i][2] for i in idxs]

Try this to unsort a sorted list

import random
li = list(range(101))
random.shuffle(li)

Here's how I recommend to sort a list, do something, then unsort back to the original ordering:

# argsort is the inverse of argsort, so we use that
# for undoing the sorting.
sorter = np.argsort(keys)
unsorter = np.argsort(sorter)

sorted_keys = np.array(keys)[sorter]

result = do_a_thing_that_preserves_order(sorted_keys)
unsorted_result = np.array(result)[unsorter]

I had the same use case and I found an easy solution for that, which is basically random the list:

import random

sorted_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
unsorted_list = random.sample(sorted_list, len(sorted_list))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top