【问题标题】:yield memory issues in pythonpython中的产生内存问题
【发布时间】:2021-01-01 13:56:05
【问题描述】:

我有一个问题 -> 我想产生信息并将其放入类似的对象中。但似乎当我将结果附加到列表时,所有内容都指向内存中的相同地址,我想。

def call(i):
    for j in range(i):
        yield j+1

def ring(i):
    obj = {}
    for j in call(i):
        obj['number'] = j
        yield obj
    
result = []
for k in ring(5):
    print(k) if k['number'] != 5 else print(k,'\n')
    result.append(k)

[print(x) for x in result]

# - OUTPUT -
#
#{'number': 1}
#{'number': 2}
#{'number': 3}
#{'number': 4}
#{'number': 5} 
#
#{'number': 5}
#{'number': 5}
#{'number': 5}
#{'number': 5}
#{'number': 5}


我想我明白这里发生了什么。但我不知道如何绕过它,我真的需要具有正确值的列表。

提前致谢:-)

【问题讨论】:

  • ring 每次都会产生相同的 obj 对象;不是副本。也许只是yield {'number': j}?如果需要新对象,则需要创建 newt 对象。
  • 顺便说一句,不要对副作用使用列表推导:[print(x) for x in result]
  • 哈哈——这将是我的新座右铭不要使用列表理解来产生副作用我刚刚去阅读它,我通过将 obj 移动到循环中解决了我的问题。这样我就可以说从等式中消除了副作用:-)

标签: python memory generator yield


【解决方案1】:

哇...你使用yield错误...为什么在保存列表时使用yield? ...您作为列表屈服并在此之后丢弃

def call(i):
    for j in range(i):
        yield j+1

def ring(i):
#you define obj here
    obj = {}
    for j in call(i):
        # if you want a different object each time instance here
        # or use obj[j] = j
        obj = {}
         
        obj['number'] = j
        # yield stop execution of this function and on next iteration continue from where it's left ... your return obj which is a reference to a dict
        yield obj
    
result = []
for k in ring(5):
    # print always puts \n after each call
    print(k) if k['number'] != 5 else print(f"{k} is 5",'\n')
    result.append(k)

[print(x) for x in result]

# - OUTPUT -
#
#{'number': 1}
#{'number': 2}
#{'number': 3}
#{'number': 4}
#{'number': 5} 
#
#{'number': 5}
#{'number': 5}
#{'number': 5}
#{'number': 5}
#{'number': 5}

我不知道你是否懂 C,但简化后的代码如下所示:

int* x = new int[10]
other* dict = new other
for (i=0;i<5;i++)
   dict.other = i
   x[i] = dict

虽然我的代码看起来像: int* x = new int[10]

for (i=0;i<5;i++)
   other* dict = new other
   dict.other = i
   x[i] = dict

【讨论】:

  • 谢谢。我知道一点C,所以我理解你的例子。这是我第一次将 yield 用于任何事情。但在我看来,我使用它而不是附加到列表并返回列表。但也许它提供的东西比我想象的要多得多:)我会在我的学习道路上找到答案,再次感谢您的回答! :)
猜你喜欢
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2011-05-05
  • 2019-09-17
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多