[英]python iterable list comprehension in list comprehension
I'm trying to figure out why my nested list comprehension doesn't work.我试图弄清楚为什么我的嵌套列表理解不起作用。 Code:
代码:
def myzip(*args):
try:
x = [iter(i) for i in [*args]]
while True:
# for i in range(5):
yield [next(ii) for ii in x]
# I want to know why the commented line below won't work
# yield [next(ii) for ii in [iter(i) for i in [*args]]]
# or why this outputs [1, 'a']
# return [next(ii) for ii in [iter(i) for i in [*args]]]
except:
pass
def main():
print(list(myzip([1, 2, 3, 4, 5], ['a', 'b', 'c'])))
if __name__ == '__main__':
main()
if I assign [iter(i) for i in [*args]]
to x
and then use this list comprehension [next(ii) for ii in x]
everything works ok.如果我将
[iter(i) for i in [*args]]
分配给x
,然后使用此列表理解[next(ii) for ii in x]
一切正常。 and the output will be: output 将是:
[[1, 'a'], [2, 'b'], [3, 'c']]
But if I try to ommit variable x
and do it in one bigger list comprehension (commented line) [next(ii) for ii in [iter(i) for i in [*args]]]
it goes in infinite loop.但是,如果我尝试省略变量
x
并在一个更大的列表理解(注释行) [next(ii) for ii in [iter(i) for i in [*args]]]
中执行它,它将进入无限循环。 If you replace infinite loop with the for loop (commented line), the output is:如果将无限循环替换为 for 循环(注释行),则 output 为:
[[1, 'a'], [1, 'a'], [1, 'a'], [1, 'a'], [1, 'a']]
Moreover, if I try return [next(ii) for ii in [iter(i) for i in [*args]]]
it just returns:此外,如果我尝试
return [next(ii) for ii in [iter(i) for i in [*args]]]
它只会返回:
[1, 'a']
Can someone tell me why is that?有人能告诉我这是为什么吗?
so i'm not going to answer your question directly (as the comments pretty well have this covered), but i am going to show how this can be done as a horrible one liner, just for fun:所以我不打算直接回答你的问题(因为评论很好地涵盖了这一点),但我将展示如何将其作为一个可怕的单线来完成,只是为了好玩:
def my_zip(*args):
yield from iter(lambda data=[iter(a) for a in args]: [next(d) for d in data], None)
there are three parts.有三个部分。
iter
, after yield from
, creates a callable_iterator
. iter
的第一次使用,在yield from
之后,创建了一个callable_iterator
。 this will repeat calling its first argument (the lambda
) until it either sees its second argument (the sentinel value, in this case None
) OR StopIteration
errorlambda
),直到它看到它的第二个参数(哨兵值,在这种情况下为None
)或者它遇到任何异常时遇到StopIteration
错误StopIteration
exception. StopIteration
异常。lambda
i have a default value for data
which is a list of the iterators you want to iterate over.lambda
中,我有一个data
的默认值,它是您要迭代的迭代器的列表。 this gets created once, so each subsequent call to the function will reference this.lambda
, i manually advance each of the iterators in data
one time per function call.lambda
的主体中,我在每个 function 调用中手动将data
中的每个迭代器推进一次。 this will continue until one of the iterators is exhausted, at which point a StopIteration
will be raised.StopIteration
。 iter
call will bail as soon as it gets its StopIteration
list
consumer which causes it to, well, stop iterating .iter
调用将在它获得StopIteration
后立即退出,list
使用者,这会导致它停止迭代。 because of the exception, the sentinel value doesn't matter. finally: please never actually do this in real code.最后:请永远不要在实际代码中实际执行此操作。
edit: some sample output编辑:一些样品 output
In [90]: list(my_zip('abcd', [1,2,3]))
Out[90]: [['a', 1], ['b', 2], ['c', 3]]
In [91]: list(my_zip('abcd', [1,2,3,4,5,6]))
Out[91]: [['a', 1], ['b', 2], ['c', 3], ['d', 4]]
explanation edits: hat tip to @superb rain for their smart comments below.解释编辑:向@superb rain 致敬,感谢他们在下面的聪明评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.