如何通过删除重复项和移动值来从现有列表中创建新列表?

时间:2013-07-05 00:21:00

标签: python list

如果我要开始以下列表:

list1 = [(12, "AB"), (12, "AB"), (12, "CD"), (13, Null), (13, "DE"), (13, "DE")]

我想把它变成以下列表:

list2 = [(12, "AB", "CD"), (13, "DE", Null)]

基本上,如果有一个或多个文本值及其关联键,则第二个列表首先具有键值,然后是文本值,然后是另一个。如果没有第二个字符串值,则如果第二个列表为空,则为项目中的第三个值。

我脑子里一遍又一遍,无法弄明白怎么做。使用set()将减少精确的重复项,但如果键值相同,则必须进行某种上一个/下一个操作来比较第二个值。

我不使用字典的原因是键值的顺序必须保持不变(12,13等)。

3 个答案:

答案 0 :(得分:3)

一种简单的方法可以多次遍历list1,每次都可以获取相关值。第一次抓住所有的钥匙。然后,对于每个键,获取所有值(repl.it):

Null = None
list1 = [(12, "AB"), (12, "AB"), (12, "CD"), (13, Null), (13, "DE"), (13, "DE")]

keys = []
for k,v in list1:
    if k not in keys:
        keys.append(k)
list2 = []
for k in keys:
    values = []
    for k2, v in list1:
        if k2 == k:
            if v not in values:
                values.append(v)
    list2.append([k] + values)

print(list2)

如果您想提高性能,我会使用字典作为中间体,因此您不必多次遍历list1repl.it):

from collections import defaultdict 
Null = None
list1 = [(12, "AB"), (12, "AB"), (12, "CD"), (13, Null), (13, "DE"), (13, "DE")]

keys = []
for k,v in list1:
    if k not in keys:
        keys.append(k)

intermediate = defaultdict(list)
for k, v  in list1:
    if v not in intermediate[k]:
        intermediate[k].append(v)

list2 = []
for k in keys:
    list2.append([k] + intermediate[k])

print(list2)

答案 1 :(得分:1)

我能看到的最简单的方法如下:

>>> from collections import OrderedDict

>>> d = OrderedDict()
>>> for (k, v) in [(12, "AB"), (12, "AB"), (12, "CD"), (13, None), (13, "DE"), (13, "DE")]:
...     if k not in d: d[k] = set()
...     d[k].add(v)

>>> d
OrderedDict([(12, {'AB', 'CD'}), (13, {'DE', None})])

或者,如果你想要列表(也会保持值顺序)并且不介意效率低一点(因为v not in ...测试必须扫描列表):

>>> d = OrderedDict()
>>> for (k, v) in [(12, "AB"), (12, "AB"), (12, "CD"), (13, None), (13, "DE"), (13, "DE")]:
...     if k not in d: d[k] = []
...     if v not in d[k]: d[k].append(v)

>>> d
OrderedDict([(12, ['AB', 'CD']), (13, [None, 'DE'])])

最后,您可以将其转换回列表:

>>> list(d.items())
[(12, ['AB', 'CD']), (13, [None, 'DE'])]
>>> [[k] + d[k] for k in d]
[[12, 'AB', 'CD'], [13, None, 'DE']]
>>> [(k,) + tuple(d[k]) for k in d]
[(12, 'AB', 'CD'), (13, None, 'DE')]

具体取决于您想要的格式。

[抱歉,之前的评论和回复误解了这个问题。]

答案 2 :(得分:0)

from collections import defaultdict

pairs = [(12, "AB"), (12, "AB"), (12, "CD"),
         (13, None), (13, "DE"), (13, "DE")]

result = defaultdict(set)
for k,v in pairs:
    result[k].add(v)

result = [(k,) + tuple(reversed(sorted(vs))) for k,vs in result.iteritems()]