将列表解除回原始序列

时间:2014-05-12 05:55:59

标签: python list sorting

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]

实际上我有一个包含(价格,数量,总计)的元组列表。 我想对列表进行排序,允许用户删除列表中的项目 然后把它放回原来的顺序减去已删除的项目。

需要注意的一点是,元组中的值可以在列表中重复, 如:

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

4 个答案:

答案 0 :(得分:4)

您不能取消列表,但您可以保留原始未排序的索引以恢复位置。

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]

如您所见,这适用于重复值。

答案 1 :(得分:1)

你无法真正做到" unsort",你能做的最好的事情是:

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

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

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

答案 2 :(得分:0)

尝试使用此方法对已排序列表进行排序

CPATH

答案 3 :(得分:0)

可以取消排序

这种方法与其他方法类似 - 其想法是保留原始索引以恢复位置。我想添加一个更清晰的示例来说明这是如何完成的。

在下面的示例中,我们通过将 a 中的项目与其列表索引相关联来跟踪它们的原始位置。

>>> 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 用作列表值与其在未排序列表中的索引之间的映射。

现在我们可以对 b 进行排序。下面,b 的每一项都按第一个元组成员排序,即原始列表中的对应值。

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

它是...排序。

回到原始顺序需要另一种排序,除了使用第二个元组项作为键。

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

现在又恢复了原来的顺序。

一种用途是将非连续值的列表转换为它们的序数值,同时保持列表顺序。例如,像 [1034 343 5 72 8997] 这样的序列可以转换为 [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]

同样的操作

>>> 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]