我有一个清单
['r', 'o', 'c', 'o', 'c', 'o']`
并希望成功
[['r','o'], ['c', 'o'], ['c', 'o']]
我该怎么做? 而且,我需要将新列表分组为“n” 在上面的例子中,n是2 如果n为3,结果应为: [['r','o','c'] ['o','c','o']]
答案 0 :(得分:7)
itertools
recipes有一个通用函数,可以使用任何类型的迭代器(名为grouper
)来完成您正在查找的内容:
>>> values = ['r', 'o', 'c', 'o', 'c', 'o']
>>> groups = grouper(values, 3)
但是,这将返回一个迭代器。如果你想要一个清单,你必须明确要求:
>>> groups = list(grouper(values, 3))
>>> print(groups)
[('r', 'o', 'c'), ('o', 'c', 'o')]
另请注意,这会为您提供元组的列表,而不是列表的列表。这很可能对你来说并不重要。但如果确实如此,你将不得不转换它们:
>>> list_groups = [list(group) for group in grouper(values, 3)]
>>> print(list_groups)
[['r', 'o', 'c'], ['o', 'c', 'o']]
如果您从PyPI安装more_itertools
,则可以from more_itertools import grouper
。否则,您必须将食谱复制并粘贴到您的代码中。
但无论哪种方式,都值得了解grouper
如何运作:
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return zip_longest(fillvalue=fillvalue, *args)
首先,它从你的iterable中创建一个迭代器。 (当你在它上面调用next
时,这会跟踪它的当前位置并逐个返回值,直到你到达终点。)然后它会对该迭代器进行n
引用。这是一个棘手的问题 - 你不希望n
将迭代器分离到同一个列表,你希望n
引用相同的迭代器,所以如果你抓住{{ 1}}从第一个迭代器中取出值,它们 all 向前移动。这就是它有趣next
位的原因。然后它只是[iter(iterable)] * n
迭代器。所以,第一个遍历第一个迭代器上的zip
调用zip
,然后是第二个,然后是第三个;第二次通过next
再次调用第一个迭代器上的zip
,然后是第二个,然后是第三个;等等。
它使用next
而不仅仅是zip_longest
(或者在Python 2.x中,zip
与izip_longest
)的原因是izip
为您list(grouper(['r', 'o', 'c', 'o'], 3))
而不仅仅是[('r', 'o', 'c'), ('o', None, None)]
。如果那不是你想要的,那么只使用其他功能是微不足道的。
有关详细说明,请参阅this blog post。
答案 1 :(得分:5)
这样的东西?
>>> a = ['r', 'o', 'c', 'o', 'c', 'o']
>>> zip(*[iter(a)]*2)
[('r', 'o'), ('c', 'o'), ('c', 'o')]
>>> zip(*[iter(a)]*3)
[('r', 'o', 'c'), ('o', 'c', 'o')]
您可以将2 and 3
更改为您想要的数字。
答案 2 :(得分:0)
[l[i:i+n] for i in range(0, len(l), n)]