【问题标题】:Python List Division/Splitting [duplicate]Python列表划分/拆分[重复]
【发布时间】:2010-07-06 06:14:17
【问题描述】:

可能重复:
How do you split a list into evenly sized chunks in Python?

你好,

我正在尝试找到一种更简单的方法来执行以下操作:

def list_split(list, size):
  result = [[]]
  while len(list) > 0:
    if len(result[-1]) >= size: result.append([])
    result[-1].append(list.pop(0))
  return result

示例用法:

>>> list_split([0, 1, 2, 3, 4, 5, 6], 2)
[[0, 1], [2, 3], [4, 5], [6]]
>>> list_split([0, 1, 2, 3, 4, 5, 6], 3)
[[0, 1, 2], [3, 4, 5], [6]]

我不知道是否有内置的方法可以做到这一点,可能是切片或其他方法。

这与How to split a list into a given number of sub-lists in python的帖子相似但不一样

谢谢

编辑: 正如 Anurag Uniyal 所评论的,这是 How do you split a list into evenly sized chunks? 的副本,应该关闭,我不能这样做。

【问题讨论】:

标签: python list split


【解决方案1】:

您可以使用切片来获取列表的子集。

例子:

>>> L = [0, 1, 2, 3, 4, 5, 6]
>>> n = 3
>>> [L[i:i+n] for i in range(0, len(L), n)]
[[0, 1, 2], [3, 4, 5], [6]]
>>>

【讨论】:

  • IMO 这是最 Pythonic 的解决方案。
  • 是的,实际上,使用 range 的 step 比我最初的方法更好。
  • +1:绝对是最明确、最清晰的列表拆分方式!它也可能比通过列表推导重建子列表更快。
  • 呃,这是使用理解,EOL。
【解决方案2】:

您在 itertools 配方 (grouper) 中有一个简单的功能解决方案:

http://docs.python.org/library/itertools.html#recipes

虽然这个函数添加了填充,但您可以轻松地编写一个非填充的实现,利用(通常被忽略的)iter 内置以这种方式使用:iter(callable, sentinel) -> iterator

def grouper(n, it):
  "grouper(3, 'ABCDEFG') --> ABC DEF G"
  return iter(lambda: list(itertools.islice(it, n)), [])

list(grouper(3, iter(mylist)))

这些解决方案更通用,因为它们都适用于序列和可迭代对象(即使它们是无限的)。

【讨论】:

  • 注:如果你忘记了iter(mylist) 中的iter,那么grouper 返回的迭代器将永远不会停止!所以总是将迭代器传递给该函数。如果您传递一个名为 L 的列表,islice(L, n) 将在每次调用时返回 L 的前 N ​​个元素。因此,除非 L 为空,否则永远无法到达 [] 哨兵。
【解决方案3】:
def list_split(L, size):
    return [L[i*size:(i+1)*size] for i in range(1+((len(L)-1)//size))]

如果您更喜欢生成器而不是列表,可以将括号替换为括号,如下所示:

def list_split(L, size):
    return (L[i*size:(i+1)*size] for i in range(1+((len(L)-1)//size)))

【讨论】:

  • 您是否真的尝试过运行此代码?另外,请不要将您的参数命名为“list”。
  • 那不行,list_split([0, 1, 2, 3, 4, 5, 6], 2) 不应该返回 [[0, 1], [2], [ ]]
  • 对不起,错字(忘记了i+1 周围的括号)。会修复的。
  • (Kenny,参数命名的唯一原因是为了反映 OP 的定义。)
  • 还是不行,list_split([0, 1, 2, 3, 4, 5, 6], 2) 不应该返回 [[0, 1], [2, 3] , [4, 5]](见原帖)
【解决方案4】:
from itertools import izip_longest

def list_split(L, size):
    return [[j for j in i if j is not None] for i in izip_longest(*[iter(L)]*size)]

>>> list_split([0, 1, 2, 3, 4, 5, 6], 2)
[[0, 1], [2, 3], [4, 5], [6]]
>>> list_split([0, 1, 2, 3, 4, 5, 6], 3)
[[0, 1, 2], [3, 4, 5], [6]]
>>> list_split([0, 1, 2, 3, 4, 5, 6], 4)
[[0, 1, 2, 3], [4, 5, 6]]
>>> list_split([0, 1, 2, 3, 4, 5, 6], 5)
[[0, 1, 2, 3, 4], [5, 6]]

【讨论】:

  • 这与 itertools 的 grouper() 配方非常相似,但删除填充使它看起来有点复杂。
猜你喜欢
  • 2019-03-04
  • 2018-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 2020-08-25
  • 1970-01-01
相关资源
最近更新 更多