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)

    输出:

  • 相关阅读:
    使用jquery.validate.js实现boostrap3的校验和验证
    MySQL 随机取数据效率问题
    qq在线客服代码
    使用Shell脚本查找程序对应的进程ID,并杀死进程
    Redis-概述
    JVM的类加载机制
    volatile
    java内存相关
    设计模式--模板方法
    设计模式概述
  • 原文地址:https://www.cnblogs.com/zftoughe-9/p/12409601.html
Copyright © 2011-2022 走看看