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