1

我有一个清单

['r', 'o', 'c', 'o', 'c', 'o']` 

并希望成功

[['r','o'], ['c', 'o'], ['c', 'o']]

我该怎么做?此外,我需要将新列表分组到上例中的任何“n”,如果 n 为 3,则 n 为 2,结果应为:[['r', 'o', 'c'][' o','c','o']]

4

3 回答 3

7

itertools食谱有一个通用功能,可以使用任何类型的迭代器完成您正在寻找的功能,称为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')]

另外,请注意,这会为您提供tuples列表,而不是lists 列表。很可能这对您来说实际上并不重要。但如果是这样,您将不得不转换它们:

>>> list_groups = [list(group) for group in grouper(values, 3)]
>>> print(list_groups)
[['r', 'o', 'c'], ['o', 'c', 'o']]

如果你安装more_itertools了 PyPI,你可以只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)

首先,它从您的可迭代对象中创建一个迭代器。(这是一种跟踪其当前位置并在您调用next它时一一返回值的东西,直到您到达终点。)然后它n引用该迭代器。这是一个棘手的问题——你不希望n对同一个列表有不同的迭代器,你希望n引用同一个迭代器,所以如果你next从第一个迭代器中获取值,它们都会向前移动。这就是为什么它做了一些有趣的事情[iter(iterable)] * n。然后它只是zip一起迭代器。因此,第一次通过对第一个迭代器的zip调用next,然后是第二个,然后是第三个;第二次通过zip再次调用next在第一个迭代器上,然后是第二个,然后是第三个;等等。

它使用zip_longest而不是 just的原因zip(或者,在 Python 2.x 中,izip_longestvs. iziplist(grouper(['r', 'o', 'c', 'o'], 3))会给你[('r', 'o', 'c'), ('o', None, None)]而不是 just [('r', 'o', 'c')]。如果这不是您想要的,那么只需使用其他功能就可以了。

如需进一步说明,请参阅此博客文章

于 2013-08-01T19:34:05.150 回答
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您想要的数字。

于 2013-08-01T19:32:15.610 回答
0
[l[i:i+n] for i in range(0, len(l), n)]
于 2013-08-01T19:35:39.727 回答