这个函数有什么作用? (Python 个迭代器)

What does this function do? (Python iterators)

def partition(n, iterable):
   p = izip_longest(*([iter(iterable)] * n))
   r = []
   for x in p:
       print(x) #I added this
       s = set(x)
       s.discard(None)
       r.append(list(s))
   return r

这实际上是在 SO 上发布的职位,作为新手,我认为这很有趣。所以你得到如下输出:

partition(5, L)
(1, 2, 3, 4, None)
Out[86]: [[1, 2, 3, 4]]

对我来说这已经令人困惑了,因为我认为 izip_longest(*([iter(iterable)] * n)) 会 运行 izip_longest 函数在 n 个相同迭代器的列表上,所以我希望首先输出 (1,1,1,1,1) 然后输出 (2,2,2,2,2) 等等。

我的问题很简短,这行是怎么回事:

 p = izip_longest(*([iter(iterable)] * n))

解析它我会认为 [iter(iterable)]*n 创建了一个长度为 n 的列表,其中包含相同的可迭代对象,它们都指向同一事物——这就是它在命令行上所做的,但这似乎不是根据上面打印的输出,它在这里做什么。

我还认为 ...longest(*... 开头的 * 在那里,因为列表的长度未知,但我认为这完全没有道理。函数调用中第一个 * 符号在做什么?它似乎并不只是表示一个未知长度的参数列表...

所以在一天结束的时候我完全迷路了。有人可以指导我了解这个语法吗?

非常感谢任何输入!


感谢大家提供的所有有用的答案。我不确定我是在解决答案还是问题,但在我看来,这个列表理解将对列表和元组做同样的事情(我意识到迭代器也适用于字典,自定义 类,其他事情...)

[L[i*n:(i+1)*n] for i in range(int(ceil(len(L)/float(n)))) ]

iter(my_list) 将列表转换为可迭代对象(即元素在看到时被消耗的列表)

[my_iter]*5 创建一个新的 [my_iter,my_iter,my_iter,my_iter,my_iter] 列表,其中所有 my_iter 都指向同一个迭代器

zip(*[my_iter,my_iter,my_iter,my_iter,my_iter]) 

相同
zip(my_iter,my_iter,my_iter,my_iter,my_iter)

(splat 只是解压一个 list/tuple)基本上只是 returns 一个 5xlen(my_list)//5 二维列表

你可以用普通的 zip 来简化它

#this method will have no `None` entries
new_list_partitioned = zip(*[iter(big_list)]*N) + [big_list[-(len(big_list)%N):],]

鉴于:

>>> li
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

有一个常见的 Python 用法,即使用 zip in combination with iter and * operator 将一个列表(一个平面列表)划分为一个长度为 n 的列表:

>>> n=3
>>> zip(*([iter(li)] * n))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14), (15, 16, 17), (18, 19, 20)]

但是,如果n不是总长度的偶数倍,则最终列表被截断:

>>> n=4
>>> zip(*([iter(li)] * n))
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15), (16, 17, 18, 19)]

您可以使用 izip_longest 为不完整的子列表使用填充有选定值的完整列表:

>>> list(izip_longest(*([iter(li)] * n)))
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15), (16, 17, 18, 19), (20, None, None, None)]