将列表列表转换为具有相同长度的列表的更嵌套列表的最佳方法是什么?

时间:2013-10-20 11:32:08

标签: python list list-comprehension

我想编写一个获取列表列表的函数,并返回相同大小的列表列表。例如,如果输入[[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. 如果我不知道列表的最大长度怎么办?
  3. 解决方案可能涉及sorted:首先对列表进行排序,以便您只需查看一次列表,只要biglist[i]biglist[i+1]大小不同,就可以将其拆分。但后来我发现自己在循环和搞乱索引,这是你通常希望避免在Python中做的事情。

    那么最快和最恐怖的方式是什么?

5 个答案:

答案 0 :(得分: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]]]

答案 1 :(得分: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]]]

答案 2 :(得分: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]]]

答案 3 :(得分: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)        

答案 4 :(得分: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)