|
|
发表于 2018-1-29 22:36:51
|
显示全部楼层
本楼为最佳答案
 以代码方式发的,你可以哪来运行下 在看看理解 如果还有不清楚欢迎联系!
写了一个多小时(好累 ),没怎么写种东西,写的差多多包涵
如果帮助你理解了,希望给个最佳
- # 我们先定义4个样例列表
- a = [x for x in range(10)]
- b = a[:]
- c = list(map(lambda x: [x, x + 1], range(0, 10, 2)))
- d = c[:]
- print(a, '\n', b, '\n', c, '\n', d)
- # 查看各个列表及其中的元素在内存中的id 看Python的处理方式
- # 查看名字的地址
- print(id(a), id(b), id(c), id(d))
- # 查看列表内元素的地址
- for i in range(5):
- print(id(a[i]), id(b[i]))
- print('----------------------------------')
- for i in range(5):
- for j in range(2):
- print(id(c[i][j]), id(d[i][j]))
- # 我们修改下值来看看
- print(id(a[0]))
- a[0] = 6
- print(id(a[0]))
- # 我们知道a[6] = 6,我们来看看a[7]
- print(id(a[6]))
- # 每次的运行结果都一样,且值相同的变量指向也是同一个内存地址
- # 这里我们甚至可以预测 我们给一个整数赋值 不用id都可以算出其内存地址
- # 据此猜测Python中对某些数据并非是创建时随机分配可用的内存地址并写入值,而是将变量名指向已经存在的值
- # 看懂上面的例子后,我们再来看for循环的实现
- # 我们先将a[0]的值改回来
- a[0] = 0
- print('-------------下面是测试1-------------------')
- count = 0
- for each in a:
- print(id(each), id(a[count]))
- each += 1
- print(id(each), id(a[count]))
- print('-------------------------------')
- count += 1
- # 是不是前后地址不一致
- print('-------------下面是测试2-------------------')
- count = 0
- for each in c:
- print(id(each), id(c[count]))
- print(id(each[0]), id(c[count][0]))
- each[0] += 1
- print(id(each), id(c[count]))
- print(id(each[0]), id(c[count][0]))
- print('-------------------------------')
- count += 1
- # 为什么这里前后地址一致呢!
- # 希望你对指针和地址的概念有一定的了解
- '''
- 1、Python中没有变量,都是标签(我们可以认为访问一个标签即是根据标签内存储的地址来访问此地址里的值,类似于C中的指针)
- C语言数组 s的地址即是s[0]的地址(这里指一维数组)
- 但从例子中我们看到id(a)和id(a[0])完全不一样 (在我看来即一个存值,一个存地址)
- 2、列表类似 当我们切片一个列表时即在不同的内存新建了一个标签
- (用'='则是公用同一个地址 b = a[:] c = a 则id(a) == id(c) != id(b),即赋值实质上是同一个,即一个人的两个名字)
- 3、一维数组和二维数组结果不同即是这种存储方式决定的
- 数组中a[0]……存储的是其值的地址
- 一维数组即是值的地址,二维数组既是另一个一维数组的地址
- 对一维数组,当for each in a时each和a[0]、a[1]……指向同一个地址,即值得地址,但本身不同 改变each只是改变each里的地址即指向,对a没有影响
- 对二维数组,当for each in a时each和a[0]、a[1]……指向同一个地址,但地址处仍是一个一维列表,这个一维列表存储的是各个值得地址,
- 当你改变each[0]、each[1]……时,改变的是其中地址的指向,与上面说的一维数组相同
- >>>>>>>但是,each和a[0]、a[1]……扔指向这个一维数组,第一次指向没有改变
- >>>>>>>所以,当你再次访问a这个列表时,会先根据地址跳到其中的一维列表,再根据一维列表的内的地址跳到数值 因为一维列表里的地址已经改变,所以a的值也会改变
- >>>>>>>而切边只是对第一层的另建一个标签,其中第二层的指向不变,所以b列表的值也会改变
- '''
- '''
- 语言表达能力比较差,不知道能不能理解,如果不太理解可以根据第3点画一个指向图,可能比较好理解
- 谢谢!!!
- '''
复制代码 |
|