Python快速创建二维数组(Python中的引用)

Python中的引用方法(列表构造)

问题

构造方法

'''
python 3.10.7 utf-8
Author: kai
Time: 2023-11-22
'''

def mxArrary_show(mxArray):
    print(mxArray, end='\n\n')
    for row in mxArray:
        print(row)
    print("----------------")


# 构造方法一
mxArray1 = [[0] * 5] * 5
# 构造方法二
mxArray2 = [[1 for i in range(5)]for j in range(5)]


mxArrary_show(mxArray1)
mxArrary_show(mxArray2)

mxArray1[1][1] = 2
mxArray2[1][1] = 2

mxArrary_show(mxArray1)
mxArrary_show(mxArray2)

创建的二维列表

[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
----------------
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]

[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
----------------

经过修改的结果

[[0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0]]

[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
----------------
[[1, 1, 1, 1, 1], [1, 2, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]

[1, 1, 1, 1, 1]
[1, 2, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
----------------

问题

为何存在

[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]
[0, 2, 0, 0, 0]

[1, 1, 1, 1, 1]
[1, 2, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1]

的修改差异。在对第[1][1]个元素进行修改的时候,mxArray[1]全都进行了更改。

原因

当创建“[0]*5”时,它确实看起来像是多次引用同一个列表,但事实并非如此。

inner_list=[0]*5

这里,“inner_list”是一个包含五个元素的列表,所有元素都是整数“0”,这创建对同一列表"[0]"的引用,它是在创建一个包含 5 个相同引用的列表,而不是创建 5 个独立的列表;最后,它创建了一个包含五个[0](列表内容为一个0)的列表(inner_list)。
现在,在嵌套列表中使用此选项时:

outer_list=[inner_list]*5

实际上,它就是重复了对同一列表对象的引用。因此,如果您修改“inner_list”的内容(例如,“inner_list[1]=42’”),您将看到“outer_list”所有元素中都反映了更改。
简言之,“[0]*5”创建一个具有五个零的新列表,而“[inner_list]*5’创建一个带有对同一列表的五个引用的列表(“inner_list”)。

问题举例

inner_list = [0]
outer_list = inner_list * 5
print(outer_list)  # 输出 [0, 0, 0, 0, 0]
outer_list[1] = 2
print(outer_list)  # 输出 [0, 2, 0, 0, 0]

在这个问题中"outer_list[1] = 2"其实是修改了outer_list[1]的值,使其为2而不是最开始引用的"inner_list".

这样子更好说明:

inner_list = [0]
outer_list = inner_list * 5

print(outer_list)

for row in outer_list:
    print(id(row))
'''
输出:
[0, 0, 0, 0, 0]
1814176465104
1814176465104
1814176465104
1814176465104
1814176465104
'''

outer_list[1] = 2
print(outer_list)

for row in outer_list:
    print(id(rowv))
'''
输出:
[0, 2, 0, 0, 0]
1814176465104
1814176465168 <
1814176465104
1814176465104
1814176465104
'''

在"outer_list[1] = 2"之后,outer_list[1]位置的id发生了变化,而outer_list其他元素仍然使用相同id(相同inner_list对象)


回到二维数组

inner_list = [0] * 5
outer_list = [inner_list] * 5

'''
outer_list = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
'''

outer_list[1][1] = 1

'''
outer_list = [[0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
'''

"outer_list[1][1] = 1"是对outer_list\[1][1]也就是inner_list(outer_list\[1])的inner_list[1]的修改,而outer_list是由 5个 相同的inner_list组成,因此 outer_list的5个元素都会发生相同的变化。

额外展示一下:


inner_list = [0] * 5
outer_list = [inner_list] * 5

print(outer_list)
for i in outer_list:
    print(id(i))

outer_list[1][1] = 1

print(outer_list)
for i in outer_list:
    print(id(i))


outer_list[1] = [2, 2, 2, 2, 2]

print(outer_list)
for i in outer_list:
    print(id(i))

'''
输出结果为:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
2186803516096
2186803516096
2186803516096
2186803516096
2186803516096
[[0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
2186803516096
2186803516096
2186803516096
2186803516096
2186803516096
[[0, 1, 0, 0, 0], [2, 2, 2, 2, 2], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
2186803516096
2186803515520
2186803516096
2186803516096
2186803516096
'''

各位也可以试试输出 内层列表 中元素 的id看看,内容比较多,这里就不贴出了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值