为什么 python 生成器结果是这样的?
Why does python generator result like this?
代码如下:
def is_subsequence(a, b):
b = iter(b)
gen = ((i in b) for i in a)
print(gen)
for i in gen:
print(i)
return all(((i in b) for i in a))
res1 = is_subsequence([1, 3, 5], [1, 2, 3, 4, 5])
res2 = is_subsequence([1, 4, 3], [1, 2, 3, 4, 5])
结果是res1==False
和res2==False
。显然 res1
的结果不正确。
当我注释掉 for 循环打印 res1==True
和 res2==False
时,这是正确的。
我很困惑。有人可以解释为什么吗?
当 b
是迭代器时,您遇到的主要问题是表达式 i in b
。检查迭代器中的成员资格会迭代这些值。它 returns True
如果找到值(消耗迭代器中的值直到并包括找到的值),或者 False
如果迭代器首先用完。不幸的是,如果您要求迭代器将以错误的顺序产生的值,您很容易错过其中的一些值。这是一个更简单的例子:
b = iter([1,2,3])
print(1 in b) # prints True
print(3 in b) # prints True, but skipped over 2 to get there
print(2 in b) # prints False, since the iterator is exhausted after seeing 3
生成器是惰性迭代器。您可以像列表一样遍历它们,但是一旦这样做,它们就会用完,即什么也没有留下。使用以下行,
gen = ((i in b) for i in a)
print(gen)
您创建一个生成器对象,然后使用以下循环,
for i in gen:
print(i)
你用尽它。顺便说一下,你在耗尽 gen
的同时也耗尽了 b
。所以到最后一行时,b
是空的,所以你的函数总是 return False。
IIUC,你想评估 a
是否是 b
的子序列(不是子集)。所以顺序很重要。您可以将函数更改为:
def is_subsequence(a, b):
b = iter(b)
return all(((i in b) for i in a))
它将按预期工作。
输出:
res1 = is_subsequence([1, 3, 5], [1, 2, 3, 4, 5]) # True
res2 = is_subsequence([1, 4, 3], [1, 2, 3, 4, 5]) # False
代码如下:
def is_subsequence(a, b):
b = iter(b)
gen = ((i in b) for i in a)
print(gen)
for i in gen:
print(i)
return all(((i in b) for i in a))
res1 = is_subsequence([1, 3, 5], [1, 2, 3, 4, 5])
res2 = is_subsequence([1, 4, 3], [1, 2, 3, 4, 5])
结果是res1==False
和res2==False
。显然 res1
的结果不正确。
当我注释掉 for 循环打印 res1==True
和 res2==False
时,这是正确的。
我很困惑。有人可以解释为什么吗?
当 b
是迭代器时,您遇到的主要问题是表达式 i in b
。检查迭代器中的成员资格会迭代这些值。它 returns True
如果找到值(消耗迭代器中的值直到并包括找到的值),或者 False
如果迭代器首先用完。不幸的是,如果您要求迭代器将以错误的顺序产生的值,您很容易错过其中的一些值。这是一个更简单的例子:
b = iter([1,2,3])
print(1 in b) # prints True
print(3 in b) # prints True, but skipped over 2 to get there
print(2 in b) # prints False, since the iterator is exhausted after seeing 3
生成器是惰性迭代器。您可以像列表一样遍历它们,但是一旦这样做,它们就会用完,即什么也没有留下。使用以下行,
gen = ((i in b) for i in a)
print(gen)
您创建一个生成器对象,然后使用以下循环,
for i in gen:
print(i)
你用尽它。顺便说一下,你在耗尽 gen
的同时也耗尽了 b
。所以到最后一行时,b
是空的,所以你的函数总是 return False。
IIUC,你想评估 a
是否是 b
的子序列(不是子集)。所以顺序很重要。您可以将函数更改为:
def is_subsequence(a, b):
b = iter(b)
return all(((i in b) for i in a))
它将按预期工作。
输出:
res1 = is_subsequence([1, 3, 5], [1, 2, 3, 4, 5]) # True
res2 = is_subsequence([1, 4, 3], [1, 2, 3, 4, 5]) # False