我有一个迭代器对象,我想将其转换为列表,但是它表现得很奇怪。
这是一个例子。这不是原始代码,仅用于生成完全相同的行为以了解问题。
class Sqrt:
def __init__(self, num):
self.original = num
self.sqrt = num * 2
class Math:
def set_value(self, num):
self.num = num
return self
def value(self):
return Sqrt(self.num)
class Counting:
def __init__(self):
self.num = 0
self.math = Math()
def __iter__(self):
return self
def __next__(self):
num = self.num
self.num += 1
if num <= 5:
m = self.math.set_value(num)
return m
raise StopIteration
c = Counting()
l = list(c)
for n in l:
print(n.value().original) # This will return 5 every time
如果您在for
循环中使用它,则一切正常。
for n in c:
print(n.value().original) # it work perfect
答案 0 :(得分:0)
行
def __next__(self):
num = self.num
self.num += 1
if num <= 5:
m = self.math.set_value(num)
return m
raise StopIteration
每次更新并返回相同的对象。在区块中
c = Counting()
l = list(c)
for n in list:
print(n.value().original)
您第一次致电next()
五次,每次更新c.math.original;然后您将打印该值五次,对于列表中的每个副本一次。当您运行
for n in c:
print(n.value().original)
您交错调用c.next()
并打印值;您仍然每次都在更新c.math.original
,但是现在您要在更新之间进行打印,因此您会看到数字1到5。
要查看发生了什么,请尝试运行
l = list(c)
for n in l:
print(id(n.value()))
和
for n in c:
print(id(n.value()))
,您会看到在每种情况下,每个对象的ID都是相同的(即,它们引用的是同一对象)。
答案 1 :(得分:0)
使用列表理解而不是for循环将返回列表。
c = Counting()
out_list = [n.value().original for n in c]
print(out_list)
输出:
[0, 1, 2, 3, 4, 5]
答案 2 :(得分:0)
这是一个普遍的问题;您将不会是第一个穿越它的人。
m
__next__()
l = list(c)
时,您有五个 same Math对象的副本。__next__()
时设置了该值m = self.math.set_value(num)
更改为m = Math().set_value(num)
您也可以尝试将print(l)
添加到代码中。您应该重复获取相同的对象ID,例如:
[<__main__.Math object at 0x7f99100d9748>, <__main__.Math object at 0x7f99100d9748>, <__main__.Math object at 0x7f99100d9748>, <__main__.Math object at 0x7f99100d9748>, <__main__.Math object at 0x7f99100d9748>, <__main__.Math object at 0x7f99100d9748>]
这可能会令人困惑。这是另一个示例:
>>> a = [5]
>>> b = [a,a,a]
>>> b
[[5], [5], [5]]
>>> b[0][0]=9
>>> b
[[9], [9], [9]]