yield 返回的数据相同

目的

从json中获取params和孙子级的id组合,获得如下格式的数据

data = [{},{},{}]

最后会提供完整的代码!

流程如下

方法一:
def get_cate_ids():
    ids = []
    with open("cate.txt", "rt",encoding='utf-8') as fp:
        for line in fp:
            data = json.loads(line)
            #判断是子集有数据
            if len(data['subcat'])>0:
                catLv1 = data["subcat"]
                for i in range(len(catLv1)):
                    #判断孙子级是否有数据
                    if len(catLv1[i]['subcat']) > 0:
                        catLv2 = catLv1[i]['subcat']
                        for j in range(len(catLv2)):
                            subids = {}
                            subids['params'] = data['params']
                            subids['id'] = catLv2[j]['id']
                            yield subids
方法二
def get_cate_ids():
    ids = []
    with open("cate.txt", "rt",encoding='utf-8') as fp:
        for line in fp:
            data = json.loads(line)
            subids = {}
            subids['params'] = data['params']
            if len(data['subcat'])>0:
                catLv1 = data["subcat"]
                for i in range(len(catLv1)):
                    if len(catLv1[i]['subcat']) > 0:
                        catLv2 = catLv1[i]['subcat']
                        for j in range(len(catLv2)):
                            subids['id'] = catLv2[j]['id']
                            yield subids

调用

ids = list(get_cate_ids())
方法一结果:
[{"params":"_version=1","id":"30020"},{"params":"_version=1","id":"30021"}]
方法二结果:
[{"params":"_version=1","id":"30021"},{"params":"_version=1","id":"30021"}]

发现由方法二产生的dict是相同的
Python用的不多,看了代码后有个模糊的感觉就是

for j in range(len(catLv2)):
    subids = {}
    subids['params'] = data['params']
    subids['id'] = catLv2[j]['id']
    yield subids

从表现来看法二中:ij都已经是最大值

为什么会这样呢?在调试中,法二如果在在yield之前打印subids输出的也是正确的数据

代码示例:

import json

def get_cate_ids():
    ids = []
    line='{"name": "高中-通用技术", "params": "_version=1", "subcat": [{"id": 30019, "title": "苏教版", "hasChild": false, "subcat": [{"id": "30020", "title": "必修一", "hasChild": true}, {"id": "30021", "title": "必修2  技术与设计2", "hasChild": true}]}]}'
    data = json.loads(line)
    #判断是子集有数据
    subids = {}
    subids['params'] = data['params']
    if len(data['subcat'])>0:
        catLv1 = data["subcat"]
        for i in range(len(catLv1)):
            # 判断孙子级是否有数据
            if len(catLv1[i]['subcat']) > 0:
                catLv2 = catLv1[i]['subcat']
                for j in range(len(catLv2)):
                    # subids = {}
                    # subids['params'] = data['params']
                    subids['id'] = catLv2[j]['id']
                    yield subids

data = list(get_cate_ids())

print(data)
Jason990420
最佳答案

因为在list(get_cate_ids())中get_cate_ids()所返回的每一个变量都指到同一个subids

所以每一次你改变subids, 同时也改变了list中的每一个变量. 如果你把

data = list(get_cate_ids())
print(data)

改成下面这样, 就会得到不同的结果. 或者你也可以使用 yield subids.copy()

for data in get_cate_ids():
    print(data)

可以到 pythontutor.com/visualize.html#mode... 检视一下是怎么回事…

3年前 评论
讨论数量: 1
Jason990420

因为在list(get_cate_ids())中get_cate_ids()所返回的每一个变量都指到同一个subids

所以每一次你改变subids, 同时也改变了list中的每一个变量. 如果你把

data = list(get_cate_ids())
print(data)

改成下面这样, 就会得到不同的结果. 或者你也可以使用 yield subids.copy()

for data in get_cate_ids():
    print(data)

可以到 pythontutor.com/visualize.html#mode... 检视一下是怎么回事…

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!