如果两个项目相同,则将列表内的列表移动到最后

Fre*_*sky 3 python list

我有以下配对值列表:

a = [['A', 'B'], ['A', 'C'], ['D', 'D'], ['C', 'D']]
Run Code Online (Sandbox Code Playgroud)

此列表可以包含一个或多个由同一项组成的卓越对:

['D', 'D']

我想将这些对移到列表的末尾以获得:

a = [['A', 'B'], ['A', 'C'], ['C', 'D'], ['D', 'D']]
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚,但我相信我并不太远:

a.append(a.pop(x) for x in range(len(a)) if a[x][0] == a[x][1])
Run Code Online (Sandbox Code Playgroud)

sch*_*ggl 9

直接排序:

a = [['A', 'B'], ['A', 'C'], ['D', 'D'], ['C', 'D']]
a = sorted(a, key=lambda x: x[0] == x[1])
# [['A', 'B'], ['A', 'C'], ['C', 'D'], ['D', 'D']]
Run Code Online (Sandbox Code Playgroud)

这个简单的键功能起作用,因为在将所有对映射到仅两个键False之前True进行排序保持稳定性.这种方法的缺点是排序是O(N_logN).对于没有不必要的列表连接的线性解决方案,您可以使用itertools.chain适当的生成器:

from itertools import chain
a = list(chain((p for p in a if p[0] != p[1]), (p for p in a if p[0] == p[1])))
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我想我现在知道为什么了.也许我会写一个问题+答案,但我首先需要完全阅读Timsort的所作所为才能确定... (2认同)

Som*_*ing 6

使用列表推导:

a = [pair for pair in a if pair[0] != pair[1]] + [pair for pair in a if pair[0] == pair[1]]
Run Code Online (Sandbox Code Playgroud)

请注意,更有效的解决方案是

identical = []
not_identical = []
for pair in a:
    if pair[0] == pair[1]:
        identical.append(pair)
    else:
        not_identical.append(pair)
a = not_identical + identical
Run Code Online (Sandbox Code Playgroud)

它更有效,因为在这里你a只迭代一次,而在列表推导解决方案中,你迭代a两次.尽管如此,这两种解决方案都需要O(n)时间复杂度和O(n)空间复杂度,这比分类解决方案更好(并且对于这个问题更自然).