2

考虑以下简化情况:

lol = [['John','Polak',5,3,7,9],
       ['John','Polak',7,9,2,3],
       ['Mark','Eden' ,0,3,3,1],
       ['Mark','Eden' ,5,1,2,9]]

根据前两个参数将此列表列表转换为列表列表列表的pythonic和内存+速度有效方法是什么:

lolol = [[['John','Polak',5,3,7,9],
          ['John','Polak',7,9,2,3]],
         [['Mark','Eden' ,0,3,3,1],
          ['Mark','Eden' ,5,1,2,9]]]

实际上 - 只要我有正确的层次结构,任何其他数据结构也可以。例如下面的字典结构浮现在脑海中,但创建它似乎效率不够高效率,而且内存可能会高于lolol解决方案。

dolol = {('John','Polak'):[[5,3,7,9],[7,9,2,3]],
         ('Mark','Eden') :[[0,3,3,1],[5,1,2,9]]}
4

3 回答 3

6

列表:

from itertools import groupby
lolol = [list(grp) for (match, grp) in groupby(lol, lambda lst: lst[:2])]
# [[['John', 'Polak', 5, 3, 7, 9], ['John', 'Polak', 7, 9, 2, 3]],
#  [['Mark', 'Eden', 0, 3, 3, 1], ['Mark', 'Eden', 5, 1, 2, 9]]]

字典:

dolol = dict((tuple(match), [x[2:] for x in grp]) for (match, grp) in 
             groupby(lol, lambda lst: lst[:2]))
# {('John', 'Polak'): [[5, 3, 7, 9], [7, 9, 2, 3]],
#  ('Mark', 'Eden'): [[0, 3, 3, 1], [5, 1, 2, 9]]}

由于itertools.groupby适用于连续匹配,因此假定输入已排序 ( lol)。

于 2011-02-12T21:59:39.227 回答
5

如果可以接受字典,则此代码将创建一个:

import collections
d = collections.defaultdict(list)
for name, surname, *stuff in lol:
    d[name, surname].append(nums)

请注意,这需要 Python 3(扩展可迭代解包)。对于 Python 2,使用

for x in lol:
    name = x[0]
    surname = x[1]
    stuff = x[2:]

您可以折叠变量以节省行数。

于 2011-02-12T20:30:31.823 回答
0

用 Python 2 等价物补充 delnan 的答案:

from collections import defaultdict

dolol=defaultdict(list)
for data in lol:
    dolol[data[0],data[1]].append(data[2:])
于 2011-02-13T07:29:18.197 回答