这个函数有什么作用? (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)]
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)]