-1

我想编写一个函数,它接受一个列表列表,并返回一个大小相等的列表列表。例如,[[1,2], [0,1], [1,2,3], [0,1,2], [1,2,3,4]]作为输入,函数应该返回[[[1,2],[0,1]], [[1,2,3],[0,1,2]], [[1,2,3,4]]]. 我知道最长列表的长度。

我的第一个直觉是为此使用列表推导:

def nestedlenlist(biglist,maxlen):
    return [[lists for lists in biglist if len(lists) == n] for n in xrange(0,maxlen)]

我对此有两个抱怨:

  1. 它在列表上迭代maxlen多次,这可能需要更长的列表时间。
  2. 如果我不知道列表的最大长度怎么办?

一个解决方案可能涉及sorted:首先对列表进行排序,以便您只需要遍历列表一次,无论何时拆分它biglist[i]并且biglist[i+1]大小不同。但是后来我发现自己在循环和搞乱索引,这是您通常希望避免在 Python 中做的事情。

那么最快和最 Pythonic 的方法是什么?

4

5 回答 5

2
In [1]: x =[[1,2], [0,1], [1,2,3], [0,1,2], [1,2,3,4]]

In [2]: result = {}

In [3]: for xx in x: result.setdefault(len(xx),[]).append(xx)

In [4]: result.values()
Out[4]: [[[1, 2], [0, 1]], [[1, 2, 3], [0, 1, 2]], [[1, 2, 3, 4]]]
于 2013-10-20T11:47:34.017 回答
1

这是一个纯粹的列表理解解决方案,但不是最好的(我认为):

origin = [[1, 2], [0, 1], [1, 2, 3], [0, 1, 2], [1, 2, 3, 4], [1]]


def list_of_lists(some_list):
    """
    This is a weird algorithm
    @type some_list: list
    @rtype : list
    @param some_list:
    """
    if len(some_list) % 2:
        return [[a, b] for a, b in zip(some_list[::2], (some_list[1::2]))] + [some_list[len(origin) - 1]]
    else:
        return [[a, b] for a, b in zip(some_list[::2], (some_list[1::2]))]

if __name__ == '__main__':
    print list_of_lists(origin)        
于 2013-10-20T11:51:01.220 回答
1
lens = [len(x) for x in biglist]
longest = max(lens)

# Need to make sure that the list of lists is not shallow copies
newlist = []
for n in range(longest):
    newlist.append 

for alist in biglist:
   x = len(alist) - 1
   newlist[x].append(alist)
于 2013-10-20T11:54:18.477 回答
1

使用collections.defaultdict

>>> from collections import defaultdict
>>> dic = defaultdict(list)
>>> lis = [[1,2], [0,1], [1,2,3], [0,1,2], [1,2,3,4]]
>>> for item in lis:
...     dic[len(item)].append(item)
...     
>>> dic.values()  # use `sorted` if you want result to be sorted by `len`
[[[1, 2], [0, 1]], [[1, 2, 3], [0, 1, 2]], [[1, 2, 3, 4]]]

或使用itertools.groupby

>>> from itertools import groupby
>>> lis = [[1,2], [0,1], [1,2,3], [0,1,2], [1,2,3,4]]
>>> sorted_lis = sorted(lis, key=len)  #sort the list based on length of items
>>> [list(g) for k, g in groupby(sorted_lis, key=len)]  
[[[1, 2], [0, 1]], [[1, 2, 3], [0, 1, 2]], [[1, 2, 3, 4]]]
于 2013-10-20T11:39:06.377 回答
1

您需要的逻辑是首先迭代列表,将子列表的每个 len 存储到一个组中,然后将它们简单地放在一个列表中。这也对它们进行排序。但如果你想走得更快,你可以不排序。

from collections import defaultdict

def bucket_list(nested_list, sort=True):
    bucket = defaultdict(list)
    for sublist in nested_list:
        bucket[len(sublist)].append(sublist)
    return [v for k,v in sorted(bucket.items())] if sort else bucket.values()

使用它:

>>> bucket_list([[1,2], [0,1], [1,2,3], [0,1,2], [1,2,3,4]])
[[[1, 2], [0, 1]], [[1, 2, 3], [0, 1, 2]], [[1, 2, 3, 4]]]
于 2013-10-20T11:39:24.437 回答