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

时间:2017-12-25 12:16:40

标签: python list

我有以下配对值列表:

a = [['A', 'B'], ['A', 'C'], ['D', 'D'], ['C', 'D']]

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

['D', 'D']

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

a = [['A', 'B'], ['A', 'C'], ['C', 'D'], ['D', 'D']]

我无法理解,但我相信我并不太远:

a.append(a.pop(x) for x in range(len(a)) if a[x][0] == a[x][1])

4 个答案:

答案 0 :(得分:9)

直接sorting

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

这个简单的key function有效,因为FalseTrue之前排序,同时将所有对映射到只有两个键维护stability。这种方法的缺点是排序是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])))

答案 1 :(得分:6)

使用列表推导:

a = [pair for pair in a if pair[0] != pair[1]] + [pair for pair in a if pair[0] == pair[1]]

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

identical = []
not_identical = []
for pair in a:
    if pair[0] == pair[1]:
        identical.append(pair)
    else:
        not_identical.append(pair)
a = not_identical + identical

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

答案 2 :(得分:0)

如果您希望原始解决方案有效,您可以做一些简单的事情:

a = [['A', 'B'], ['A', 'C'], ['D', 'D'], ['C', 'D']]

for i, pair in enumerate(a):
    if pair[0] == pair[1]:
        a.append(a.pop(i))

print(a)
# [['A', 'B'], ['A', 'C'], ['C', 'D'], ['D', 'D']]

这是O(N^2),因为for循环中的pop(i)O(N)本身。如果从列表末尾弹出,pop()仅为O(1)

您还可以按照列表集的长度使用字典进行分组,如果您最后避免排序,只需使用O(N)min(),这两个都是max() O(N)次操作。

以下是一个例子:

from collections import defaultdict

a = [['A', 'B'], ['A', 'C'], ['D', 'D'], ['C', 'D']]

d = defaultdict(list)
for sublst in a:
    key = len(set(sublst))
    d[key].append(sublst)

result = result = d[max(d)] + d[min(d)]

print(result)
# [['A', 'B'], ['A', 'C'], ['C', 'D'], ['D', 'D']]

当然,如@schwobaseggl所示,您也可以接受O(NlogN)排序方法:

sorted(a, key = lambda x: -len(set(x)))

答案 3 :(得分:-1)

只需收集列表中的所有重复项,最后扩展列表:

a = [['A', 'B'], ['A', 'C'], ['D', 'D'], ['C', 'D']]

no_dub=[]
dub=[]
for i in a:
    if i[0]==i[1]:
        dub.append(i)
    else:
        no_dub.append(i)

no_dub.extend(dub)
print(no_dub)

输出:

[['A', 'B'], ['A', 'C'], ['C', 'D'], ['D', 'D']]