为每个唯一值创建列表
Create list for each unique value
我目前正在查看具有以下结构的 table。
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])
你可以使用旧的 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']]
这应该可以,但似乎 groupby
已经非常好。
uids = {}
for row in table:
uids.setdefault(row['uid'], []).append(row['action'])
data = [uids[uid] for uid in sorted(uids.keys())]
该解决方案只是遍历 table
中的每一行,并确保在 uids
字典中有一个对应 uid 的列表(使用 setdefault
)。然后它将该行的操作附加到列表中。
因此 uids
将是一个字典,其键是 UID,值是 table.
中相应操作的序列
如果你真的想要一个列表的列表(一个"multidimensional array"),最后一行使用列表理解来构建一个列表,其元素是存储在uids
字典中的动作列表,按 uid 排序。
根据,
@Black Are you sure that the data is ordered?
... @thefourtheye, yes pretty sure as I've had to write it in sql before reading it into 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']]
我目前正在查看具有以下结构的 table。
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])
你可以使用旧的 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']]
这应该可以,但似乎 groupby
已经非常好。
uids = {}
for row in table:
uids.setdefault(row['uid'], []).append(row['action'])
data = [uids[uid] for uid in sorted(uids.keys())]
该解决方案只是遍历 table
中的每一行,并确保在 uids
字典中有一个对应 uid 的列表(使用 setdefault
)。然后它将该行的操作附加到列表中。
因此 uids
将是一个字典,其键是 UID,值是 table.
如果你真的想要一个列表的列表(一个"multidimensional array"),最后一行使用列表理解来构建一个列表,其元素是存储在uids
字典中的动作列表,按 uid 排序。
根据
@Black Are you sure that the data is ordered?
... @thefourtheye, yes pretty sure as I've had to write it in sql before reading it into 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']]