python使用yield中出现的问题

python yield使用过程出现一个不知道为什么行不通的点

a = [1,2,3,4,5]

def aaa(a):
    for i in range(0,len(a)):
        a.remove(a[0])
        yield a

result =[]
for i in range(0,5):
    result1 = next(aaa(a))
    result.append(result1)
print(result)
print(result[-2])

[[], [], [], [], []]
[]

另一种书写

a = [1,2,3,4,5]

def aaa(a):
    for i in range(0,len(a)):
        a.remove(a[0])
        yield a

result =[]
for i in range(0,5):
    result1 = next(aaa(a))
    result.append(list(result1))
print(result)
print(result[-2])

[[2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []]
[5]
为什么呢,求各位指教

实际上是如下代码

# 第一种情况,实际上是如下代码
a = [1,2,3,4,5]
print("a的地址是", id(a))

def aaa(a):
    for i in range(0,len(a)):
        a.remove(a[0])
        yield a

result =[]
for i in range(0,5):
    result1 = next(aaa(a))
    # 这种情况实际上是python的浅拷贝现象,追加进去的元素,实际上还都是指向的a,在内存中是同一块内存地址
    print("result1的地址是:", id(result1))
    # result1 实际上就是a
    result.append(result1)
print(result)


# 第二种情况是进行了深拷贝

a = [1,2,3,4,5]
print("a的地址是", id(a))
def aaa(a):
    for i in range(0,len(a)):
        a.remove(a[0])
        yield a

result =[]
for i in range(0,5):
    result1 = next(aaa(a))
    # 这里是进行了深拷贝,new_a不在指向原来的a的内存地址,而是在内存中复制了一份新的数据,第一种情况是都是指向的a列表,所以第一种情况下 a列表的元素被删除,其他的也会跟着被删除
    new_a = list(result1)
    print("new_a的内存地址是:", id(new_a))
    result.append(new_a )
print(result)

参考GPT和自己的思路:

这是因为在使用yield生成器时,每次调用next()函数时,会从上一次yield语句停止的地方继续执行,所以在这个例子中,每次调用next()函数时,会执行到下一个循环迭代,而不是从头开始执行。在这个例子中,当a列表被修改时,yield语句生成的值也会被更改,导致结果不符合预期。建议避免在yield语句中修改迭代器。如果要生成修改后的列表,可以创建一个新的列表并将其yield出去。另外,使用Python内置的切片(slice)语句可以更方便地实现对列表的操作,而不会改变原有列表。以下是修改后的代码:

a = [1,2,3,4,5]

def aaa(a):
    for i in range(len(a)):
        yield a[i+1:]

result = []
for i in range(5):
    result1 = next(aaa(a))
    result.append(list(result1))
print(result)
print(result[-2])

输出为:

[[2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []]
[5]

这个代码使用了切片语句来获取每个索引后的值,从而得到修改后的列表,并将其yield出去。同时,为了避免在循环中去除列表的第一个元素,循环的范围也做了修改。

参考GPT和自己的思路:

你好!根据你提供的代码,其中的问题在于在 for 循环过程中,不断对列表 a 进行了修改,导致 yield 函数每次的返回结果并非你所期望的。具体来说,当你修改了 a 后,yield 返回的结果也会受到影响,因此最终得到的结果并非你想要的。

解决这个问题的办法是,在每次循环前先创建一个 a 的副本,再对副本进行操作。代码如下:

a = [1,2,3,4,5]

def aaa(a):
    for i in range(len(a)):
        b = a[:]
        b.remove(a[0])
        yield b

result = []
for i in range(len(a)):
    result1 = next(aaa(a))
    result.append(result1)

print(result)
print(result[-2])

这样,就可以正常得到你想要的结果了。