在 Python 中,将一个列表(`list`)每 N 个元素分割成多个子列表(即“分组”或“分块”),是一个非常常见的需求。以下是几种高效且常用的实现方法。
---
### ✅ 方法一:使用列表推导式 + 切片(最常用)
```python
def chunk_list(lst, n):
"""将列表 lst 每 n 个元素分成一个子列表"""
return [lst[i:i + n] for i in range(0, len(lst), n)]
# 示例
original_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
n = 3
result = chunk_list(original_list, n)
print(result)
# 输出: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
```
> 🔍 解释:
- `range(0, len(lst), n)`:每次步进 `n`;
- `lst[i:i+n]`:切片取 `n` 个元素;
- 最后一组不足 `n` 个也会保留。
---
### ✅ 方法二:使用生成器(节省内存,适合大列表)
```python
def chunk_generator(lst, n):
"""返回一个生成器,每次产出一个大小为 n 的块"""
for i in range(0, len(lst), n):
yield lst[i:i + n]
# 示例
original_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
n = 4
for chunk in chunk_generator(original_list, n):
print(chunk)
# 输出:
# [1, 2, 3, 4]
# [5, 6, 7, 8]
# [9]
```
> 🧠 优点:不一次性加载所有子列表到内存,适用于处理大数据集。
---
### ✅ 方法三:使用 `itertools` 实现通用分块(高级技巧)
```python
from itertools import islice
def chunked_iterable(iterable, n):
"""适用于任意可迭代对象的分块"""
iterator = iter(iterable)
while True:
chunk = list(islice(iterator, n))
if not chunk:
break
yield chunk
# 示例
data = range(1, 11) # 可迭代对象
result = list(chunked_iterable(data, 3))
print(result)
# 输出: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
```
> ✅ 优势:不仅适用于 `list`,也适用于文件、生成器等流式数据。
---
### ✅ 方法四:使用第三方库 `more-itertools`(推荐生产环境)
#### 安装:
```bash
pip install more-itertools
```
#### 使用:
```python
from more_itertools import chunked
original_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = list(chunked(original_list, 3))
print(result)
# 输出: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
```
> 💡 提示:该库还提供 `ichunked`(惰性迭代)、`chunked_even` 等增强功能。
---
### ⚠️ 注意事项
- 如果原列表长度不能被 `n` 整除,最后一组会少于 `n` 个元素;
- 切片方式不会修改原始列表;
- 若需填充最后一组至满 `n` 个,可手动补值(如 `None`):
```python
def chunk_with_padding(lst, n, pad_value=None):
result = [lst[i:i + n] for i in range(0, len(lst), n)]
last = result[-1]
if len(last) < n:
last.extend([pad_value] * (n - len(last)))
return result
print(chunk_with_padding([1, 2, 3, 4, 5], 3, 0))
# 输出: [[1, 2, 3], [4, 5, 0]]
```
---
### ✅ 总结对比
| 方法 | 是否推荐 | 说明 |
|------|----------|------|
| 列表推导 + 切片 | ✅✅ 推荐 | 简洁、易懂、高效 |
| 生成器 | ✅ 大数据用 | 内存友好 |
| `itertools.islice` | ✅ 通用场景 | 支持任意可迭代对象 |
| `more-itertools.chunked` | ✅✅ 生产推荐 | 功能完整,代码干净 |
---