1

If I have the following list to start:

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

I want to turn it into the following list:

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

Basically, if there is one or more text values with their associated keys, the second list has the key value first, then one the text value, then the other. If there is no second string value, then the third value in the item if the second list is Null.

I've gone over and over this in my head and cannot figure out how to do it. Using set() will cut down on exact duplicates, but there is going to have to be some sort of previous/next operation to compare the second values if the key values are the same.

The reason I am not using a dictionary is that the order of the key values has to stay the same (12, 13, etc.).

4

3 回答 3

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)
于 2013-07-05T00:42:16.330 回答
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')]

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

[对不起,之前的评论和回复误解了这个问题。]

于 2013-07-05T00:38:06.783 回答
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()]
于 2013-07-05T05:04:14.317 回答