为每个唯一值创建列表

时间:2015-03-17 12:12:29

标签: python list grouping

我目前正在查看具有以下结构的表格。

uid | action
 1  |   A1
 1  |   A1
 1  |   A1
 1  |   A4
 2  |   A1
 2  |   A8
 2  |   A9
 3  |   A3
 3  |   A7

我试图创建一个具有以下结构的多维数组。

[[A1, A1, A1, A4], [A1, A8, A9], [A3, A7]] 

我的想法是跟踪uid并将操作附加到列表中,直到uid键更改为止。一旦uid密钥发生变化,所有操作都将附加到另一个数组,被跟踪的uid将更改为新的uid

我使用itertools.groupby()提出了一个过于夸张且不正确的解决方案,但我对此并不满意,并且正在寻找更简单的方法。但是,我已经推翻了这个问题,并提出了更复杂的解决方案。

任何提示都将不胜感激。

代码:

data = []
for i, j in itertools.groupby(table, key=lambda x: x['uid']):
    event_array = []
    for k in list(j):
        event_array.append(k['action'])
    data.append([i, event_array])

3 个答案:

答案 0 :(得分:3)

根据OP's comment

  

@Black您确定数据已订购吗?

     

... @thefourtheye,是的非常确定,因为我必须在sql中将其写入之前将其读入python

由于数据已经订购,例如,像这样

>>> data = [{'action': 'A1', 'uid': 1},
...  {'action': 'A1', 'uid': 1},
...  {'action': 'A1', 'uid': 1},
...  {'action': 'A4', 'uid': 1},
...  {'action': 'A1', 'uid': 2},
...  {'action': 'A8', 'uid': 2},
...  {'action': 'A9', 'uid': 2},
...  {'action': 'A3', 'uid': 3},
...  {'action': 'A7', 'uid': 3}]

你可以简单地使用groupby本身,使用嵌套列表理解,就像这样

>>> [[k['action'] for k in j] for i, j in groupby(data, key=lambda x: x['uid'])]
[['A1', 'A1', 'A1', 'A4'], ['A1', 'A8', 'A9'], ['A3', 'A7']]

答案 1 :(得分:2)

您可以使用优秀的旧defaultdict

from collections import defaultdict

DATA = [{'uid': uid, 'action': action}
        for uid, action in [(1, 'A1'),
                            (1, 'A1'),
                            (1, 'A1'),
                            (1, 'A4'),
                            (2, 'A1'),
                            (2, 'A8'),
                            (2, 'A9'),
                            (3, 'A3'),
                            (3, 'A7'),]]

d = defaultdict(list)

for data in DATA:
    d[data['uid']].append(data['action'])

print(d.values())

结果将是:

[['A1', 'A1', 'A1', 'A4'], ['A1', 'A8', 'A9'], ['A3', 'A7']]

答案 2 :(得分:1)

这应该有效,但似乎groupby已经非常好了。

uids = {}
for row in table:
    uids.setdefault(row['uid'], []).append(row['action'])

data = [uids[uid] for uid in sorted(uids.keys())]

解决方案只是迭代table中的每一行,并确保uids dict中有相应uid的列表(使用setdefault)。然后它将该行的操作追加到列表中。

因此uids将是一个字典,其键是UID,值是表中相应操作的序列。

如果你真的想要一个列表列表(一个“多维数组”),最后一行使用列表推导来构建一个列表,其元素是存储在uids dict中的动作列表,由uid排序