3

如果我在 python 中有一个列表说

thing = [[20,0,1],[20,0,2],[20,1,1],[20,0],[30,1,1]]

我想要一个结果列表

thing = [[20,1,1],[20,0,2],[30,1,1]]

即如果第一个元素相同,则去掉重复项,优先考虑第二个元素中的数字1。最后,第三个元素也必须对第一个元素是唯一的。

上一个问题中,我们解决了一个复杂的方法,其中交易详细说明了购买的单位。我想在该课程中输出其他单位。如果存在与一门课程中的两个单元相关的两个事务,它将显示它们重复(或每个后续单元的倍数)。

这个问题的目的是确保停止这种重复。由于该解决方案的复杂性,它导致了一系列问题。感谢迄今为止提供帮助的所有人。

4

3 回答 3

2

我不确定你会喜欢这个,但它适用于你的例子:

[list(i) + j for i, j in dict([(tuple(x[:2]), x[2:]) for x in sorted(thing, key=lambda x:len(x))]).items()]

编辑:

这里更详细一点(请注意,它更适合您对问题的描述,仅按每个子列表的长度排序,可能不是最佳解决方案):

thing = [[20,0,1],[20,0,2],[20,1,1],[20,0],[30,1,1]]
dico = {}
for x in thing:
    if not tuple(x[:2]) in dico:
        dico[tuple(x[:2])] = x[2:]
        continue
    if tuple(x[:2])[1] < x[1]:
        dico[tuple(x[:2])] = x[2:]

new_thing = []
for i, j in dico.items():
    new_thing.append(list(i) + j)
于 2013-07-26T12:04:26.813 回答
2

您可能想尝试使用itertools recipesunique_everseen中的函数。

作为第一步,这是一个解决方案,不包括[20, 0]

from itertools import filterfalse

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in filterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

thing = [[20,0,1],[20,0,2],[20,1,1],[30,1,1]]

thing.sort(key=lambda x: 0 if x[1] == 1 else 1)

print(list(unique_everseen(thing, key=lambda x: (x[0], x[2]))))

输出:

[[20, 1, 1], [30, 1, 1], [20, 0, 2]]
于 2013-07-26T12:20:13.597 回答
2
thing = [[20,0,1],[20,0,2],[20,1,1],[20,0,1],[30,1,1]]

d = {}
for e in thing:
    k = (e[0], e[2])
    if k not in d or (d[k][1] != 1 and e[1] == 1):
        d[k] = list(e)

print d.values()

[[20, 0, 2], [30, 1, 1], [20, 1, 1]]

如果您不需要初始列表:

thing = [[20,0,1],[20,0,2],[20,1,1],[20,0,1],[30,1,1]]

d = {}
for e in thing:
    k = (e[0], e[2])
    if k not in d or (d[k][1] != 1 and e[1] == 1):
        d[k] = e

thing = d.values()

[[20, 0, 2], [30, 1, 1], [20, 1, 1]]

如果您想保持列表的顺序,请使用 OrderedDict

from collections import OrderedDict
d = OrderedDict()
于 2013-07-26T12:22:44.367 回答