将迭代器转换为python中的列表

时间:2019-11-16 05:43:53

标签: python

我有一个迭代器对象,我想将其转换为列表,但是它表现得很奇怪。
这是一个例子。这不是原始代码,仅用于生成完全相同的行为以了解问题。

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

3 个答案:

答案 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
  • 时,您返回 same 对象__next__()
  • 执行l = list(c)时,您有五个 same Math对象的副本。
  • 该对象中的值为5,您在上次调用__next__()时设置了该值
  • 在for循环中打印时,您仍在重复使用相同的数学对象,但是会在值更改之前进行打印,以进行下一次迭代。
  • 如果要解决此问题,可以将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]]