判断id是否相同使用 is,而判断值是否相同使用==。
a=10
b=a
c=10
print(id(a),id(b),id(c))
#1950969600 1950969600 1950969600
b=10+0
c=10+1
print(id(a),id(b),id(c))
#1950969600 1950969600 1950969632
print(id(11))
#1950969632
再来看一下如果a、b、c都改变了原来的内存块是怎么处理的:
a=b=c=13
print(id(a),id(b),id(c))
#1950969696 1950969696 1950969696
print(id(10),id(11))
#1950969600 1950969632
可以发现10和11的内存块依旧存在,暂时不清楚python的垃圾回收机制,待后续继续研究。
2.字符串:
发现一个神奇的问题,先看下面三段代码:
astr="Helloworld"
bstr="Helloworld"
print(id(astr),id(bstr))
#2235114515248 2235114515248
bstr+=""
print(id(astr),id(bstr))
#2235114515248 2235114515248
########################################
astr="Helloworld!"
bstr="Helloworld!"
print(id(astr),id(bstr))
#2235114479664 2235114482032
bstr+=""
print(id(astr),id(bstr))
#2235114479664 2235114482032
astr==bstr
#True
#########################################
astr="Hello world"
bstr="Hello world"
print(id(astr),id(bstr))
#2235114497200 2235114545264
bstr+=""
print(id(astr),id(bstr))
#2235114497200 2235114545264
astr==bstr
#True
可以看到字符串中如果只有字母,两个对象指向同一个地址,然而!!当字符串中出现了空格或者‘!’之类的符号时,两个对象虽然内容相同,但是指向的地址却不同了。这个原因有待考究。
3.元祖tuple
add = (1, 2, 3)
aee = (1, 2, 3)
print(id(add), id(aee), id((1, 2, 3))) # id各不相同
#2235094251128 2235094238120 2235094250624
aee = (1, 2, 3)
print(id(aee)) #2235114527624
aee += () # 加空元组
print(id(aee)) # id变了!
#2235094251056
print(aee)
#(1, 2, 3)
虽然看上去都是(1 ,2, 3)
按理说应该和上面一致才对。难道这是可变对象?再看
add = (1, 2, 3)
aee = add
print(id(aee), id(add)) # 这两个id一样
#2235094238048 2235094238048
aee += (4, 5, 6)
print(id(aee), id(add)) # aee的id变了,add的id没有变。
#2235114527624 2235094238048
print(add) # add还是(1, 2, 3)没有变
#(1, 2, 3)
又和数值类型于str类型一致了。如果是可变对象add = aee
,它们指向同一地址(id相同)是肯定的。但不是同一对象的不同引用,因为如果是的话,aee的改变会引起add的改变,再tuple中并不是这样。所以tuple是不可变对象,但又和str和数值类型稍微有点区别。平常说的tuple不可变更多时候是指里面存放的值不能被改变(有些特殊情况,如tuple里面存放了list,可改变list里的元素。但实际上这个tuple并没有被改变)。
list1=[1,2,3]
list2=[1,2,3]
print(id(list1),id(list2),id([1,2,3]))
#2235114547208 2235114560648 2235114547016
三个list指向不同的id,再看
alist = [1, 2, 3]
# alist实际上是对对象的引用,blist = alist即引用的传递,现在两个引用都指向了同一个对象(地址)
blist = alist
print(id(alist), id(blist)) # id一样
#2235114533832 2235114533832
# 所以其中一个变化,会影响到另外一个
blist.append(4)
print(alist) # 改变blist, alist也变成了[1 ,2 ,3 4]
#[1 ,2 ,3 4]
print(id(alist), id(blist)) # id一样,和上面值没有改变时候的id也一样
#2235114533832 2235114533832
blist = alist[:] # or alist.copy()
print(alist is blist) # False
blist.append(4)
print(alist) # 还是[1,2 ,3]没有变化
关于list的
+=
的问题:
a1 = [1, 2, 3]
a2 = a1
print(id(a1), id(a2))
a2 += [4] # 相当于调用了a2.extend([4]),原地改变并没有新的对象产生
print(id(1), id(a2)) # 相等,a2的id没有变化
print(a1)
abb = {1, 2, 3}
acc = abb
print(id(abb), id(acc))
#2235113206504 2235113206504
acc.add(4)
print(abb)
# {1, 2, 3, 4}
print(id(abb), id(acc))
#2235113206504 2235113206504
可以看到和list是一样的。