Python 最近遇到的两个小 BUG

1. 列表通过 append 添加元素时添加的是对象的引用,列表通过 append 等方法进行操作时不改变引用

错误代码

import numpy as np

data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
a = []
b = []
for i in range(data.shape[0]):
    a.clear()
    for j in range(data.shape[1])):
        a.append(data[i][j])
    b.append(a)

print(a) #  [7, 8, 9]
print(b) # [[7, 8, 9], [7, 8, 9], [7, 8, 9]]

错误分析

本例的目的是通过建立一个临时变量 a ,来将数组中的内容复制到列表 b 中。当然,这只是为了说明问题而随便写的一段代码,不具有实际作用。

实际上,列表 b 通过 append 方法新增了一个元素 a 后,列表中的元素和 a 此时引用自同一个对象,而 a 再通过 clear 和 append 方法进行操作时,引用不变,此时,改变了 a 也就改变了列表 b 中的元素。但是,若 a 通过赋值方式改变数值,则相当于引用了新的对象,此时改变 a 则列表 b 中的元素不受影响。

2. Numpy 数组中每个元素占用内存大小是固定的,修改元素值时不能超越对应的内存大小

错误代码

import numpy as np
import sys

a = np.load('image_name.npy')
print(a[0])                                        # 047b0428bd6841b872023ac8ae1c69c9.jpeg
print(type(a[0]))                                  # <class 'numpy.str_'>
a[0] = a[0] + 'python' 
print(a[0])                                        # 047b0428bd6841b872023ac8ae1c69c9.jpeg
print(a[0] + 'python')                             # 047b0428bd6841b872023ac8ae1c69c9.jpegpython
print(type(a[0] + 'python'))                       # <class 'str'>
a[0] = 'python'
print(a[0])                                        # python
print(sys.getsizeof(a[0]))                         # 118
print(sys.getsizeof(np.str_('047b0428bd6841b872023ac8ae1c69c9.jpeg')))       # 118
print(sys.getsizeof(np.str_('047b0428bd6841b872023ac8ae1c69c9.jpegpython'))) # 124

错误分析

a[0] 占用内存大小为 118 ,因此将一个占用内存大小为 124 的字符串赋值给 a[0] 时,只能将截取前面的部分,而无法实现我们想要进行的字符串拼接操作。

获取更多精彩,请关注「seniusen」!

《Python 最近遇到的两个小 BUG》 seniusen

    原文作者:seniusen
    原文地址: https://www.jianshu.com/p/c4bb37864be2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞