zoukankan      html  css  js  c++  java
  • python循环中对一个列表的赋值问题

    参考:https://www.cnblogs.com/zf-blog/p/10613981.html

               https://www.cnblogs.com/andywenzhi/p/7453374.html?tdsourcetag=s_pcqq_aiomsg

    python的赋值方式是数据建立内存单元,将数据存入内存,然后再将变量名指向存储了数据的内存单元,如下图示:

    不同于c的赋值方式:先为变量分配内存,然后再将变量的数据存入内存。

    为了节省内存,如果将一个变量的值赋值给另一个变量,比如,b = 3, a = b, 

     变量a和b有完全一致的ID(指向同一内存地址)。

    由于上述机制的存在,实际上没有为变量a分配内存,只是将a指向了变量b指向的内存地址。若对此不加注意,初学者就有可能出现感觉

    很“怪异”的错误。比如有两个列表:

    x = [[2, 3]]
    y = [[4, 5], [5, 6], [7, 8], [9, 10]]

     期望将y列表中的每个元素添加到x列表中组成新的列表z[i],所有的z[i]将组成新的列表:

    z = 

    [[[2, 3],[4, 5]],[[2, 3],[5, 6]],[[2, 3],[7, 8]],[[2, 3],[9, 10]]]

    如果这样编写程序:

    def list2list(list_a, list_b):
    list_mix, len_e = [], len(list_b)
    for j in range(len_e):
    list_c = list_a
    id(list_c)
    id(list_a)
    print("改变list_c赋值之前二者id:", id(list_c), id(list_a))
    list_c.append(list_b[j])
    id(list_c)
    id(list_a)
    print("改变list_c赋值之后二者id:", id(list_c), id(list_a))
    list_mix.append(list_c)
    return list_mix


    x = [[2, 3]]
    y = [[4, 5], [5, 6], [7, 8], [9, 10]]


    if __name__ == '__main__':
    z = list2list(x, y)
    print(z)

     其输出为:

    改变list_c赋值之前二者id: 53391968 53391968
    改变list_c赋值之后二者id: 53391968 53391968
    改变list_c赋值之前二者id: 53391968 53391968
    改变list_c赋值之后二者id: 53391968 53391968
    改变list_c赋值之前二者id: 53391968 53391968
    改变list_c赋值之后二者id: 53391968 53391968
    改变list_c赋值之前二者id: 53391968 53391968
    改变list_c赋值之后二者id: 53391968 53391968
    [[[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]], [[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]], [[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]], [[2, 3], [4, 5], [5, 6], [7, 8], [9, 10]]]

    从中可以看出,无论有没有对列表list_c的赋值进行添加更改,列表list_c和list_a的id都是完全一致的,这表明二者共用了内存地址。若对其中一个列表

    list_c的赋值进行更改,则对应内存地址中的数据将更改,由于另一列表list_a与其共用数据内存,所以list_a的赋值也被“莫名其妙”地更改了,导致输出

    结果与预期大相径庭。关键问题在于列表赋值更改方式(.append)。可对比下例:

    def add02(a, b):
    len_b = len(b)
    d = []
    for i in range(len_b):
    c = a
    print("c和a赋值更改前的id:", id(c), id(a))
    c += 1
    print("c和a赋值更改后的id:", id(c), id(a))
    e = c + b[i]
    d.append(e)
    return d


    x = 5
    y = [6, 7, 8, 9, 10]


    if __name__ == '__main__':
    z = add02(x, y)
    print(z)

    输出:

    c和a赋值更改前的id: 259024032 259024032
    c和a赋值更改后的id: 259024048 259024032
    c和a赋值更改前的id: 259024032 259024032
    c和a赋值更改后的id: 259024048 259024032
    c和a赋值更改前的id: 259024032 259024032
    c和a赋值更改后的id: 259024048 259024032
    c和a赋值更改前的id: 259024032 259024032
    c和a赋值更改后的id: 259024048 259024032
    c和a赋值更改前的id: 259024032 259024032
    c和a赋值更改后的id: 259024048 259024032
    [12, 13, 14, 15, 16]

    可将上文中list2list()改为:

    def add_element(a, b):
    c = a + b
    return c


    def list2list(list_b, list_e):
    list_mix, len_e = [], len(list_e)
    list_c = list_b * len_e
    list_mix = list(map(add_element, list_c, list_e))
    return list_mix


    if __name__ == '__main__':
    x = [[[2, 3]]]
    y = [[[4, 5]], [[5, 6]], [[7, 8]], [[9, 10]]]
    route = list2list(x, y)
    print("route:", route)

    输出:

  • 相关阅读:
    java Activiti 工作流引擎 SSM 框架模块设计方案
    自定义表单 Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    数据库设计的十个最佳实践
    activiti 汉化 stencilset.json 文件内容
    JAVA oa 办公系统模块 设计方案
    java 考试系统 在线学习 视频直播 人脸识别 springboot框架 前后分离 PC和手机端
    集成 nacos注册中心配置使用
    “感恩节 ”怼记
    仓颉编程语言的一点期望
    关于System.out.println()与System.out.print("\n")的区别
  • 原文地址:https://www.cnblogs.com/zftoughe-9/p/12409601.html
Copyright © 2011-2022 走看看