python 在线

896Python 运算符

Python 基础的发现个问题,有一个列表 a=[1,2,3,4,5],赋值给 b 的两种方式:

# 第一种
b=a 

# 第一种
b=a[:]

结果都是: [1, 2, 3, 4, 5]

这两种赋值结果看起来都是一样的,但是他们有什么区别么?

区别就是:

  • 前者传递引用
  • 后者是拷贝

Python 有个叫做 id 的函数能够得到对象的地址,你打印出来看看就清楚了。直接 = 是引用赋值,引用原来的对象;而 [:] 是重新推导,会生成新的对象。

>>> a=[1,2,3,4,5]
>>> b=a
>>> c=a[:]
>>> id(a)
4410359536
>>> id(b)
4410359536
>>> id(c)
4410358240

从以上结果上看 id(a) 与 id(b) 的内存地址一样的,而 id(a) 与 id(c) 内存地址不一样。

895Python 运算符

Python 中没有 ++ 或 -- 自运算符

因为在 Python 里的数值和字符串之类的都是不可变对象,对不可变对象操作的结果都会生成一个新的对象。

比如:

a = 1
a += 1

在 C/java 之类的语言中,把 a 指向内存地址单元数据值由 1 改成了 2。

但是在 Python 中是完全不同的另一套机制。

解释器创建一个新的整数对象 2。

然后把这个对象的地址再次分配给 a。

见下面代码:

>>> id(1)
41116008L
>>> a = 1
>>> id(a)
41116008L
>>> id(2)
41115984L
>>>a += 1
>>> id(a)
41115984L
>>> 

所以在 Python 中不可能出现C/java 之类那种单独一行一个 i++i-- 的。

894Python 运算符

如果变量写在同一行,将会指向同一个对象

>>> a=4444; b=4444;   # 写在同一行
>>> a is b
True
>>> a == b
True

>>> c = 5555   # 写在不同一行
>>> d = 5555   # 写在不同一行
>>> c is d
False
>>> c == d
True
>>> 

以上情况在交互模式会出现,使用脚本运行,不管是否同一行,都是指向同一个地址:

# -*- coding: utf-8 -*-

a = 4444; b = 4444
print(a is b)          # true

c = 5555
d = 5555
print(c is d)          # true

893Python 运算符

这里 is== 类似编译原理中传值与传地址。又或者说是 is 只是传递的指针,判断是否指向同一个地址块,这样 is 两边的参数指向内存中同个地址块,毕竟我家电视跟你电视不是同一个东西。而 == 则是仅仅判断值相同

892Python 运算符

以下测试情况会在交互模式下出现,脚本模式 is 和 == 结果是一样的。

python中会为每个出现的对象分配内存,哪怕他们的值完全相等(注意是相等不是相同)。如执行a=2.0,b=2.0这两个语句时会先后为2.0这个Float类型对象分配内存,然后将a与b分别指向这两个对象。所以a与b指向的不是同一对象:

>>> a=2.0
>>> b=2.0
>>> a is b
False
>>> a==b
True
>>> e

但是为了提高内存利用效率对于一些简单的对象,如一些数值较小的int对象,python采取重用对象内存的办法,如指向a=2,b=2时,由于2作为简单的int类型且数值小,python不会两次为其分配内存,而是只分配一次,然后将a与b同时指向已分配的对象:

>>> a=2
>>> b=2
>>> a is b
True
>>> a==b
True

如但果赋值的不是2而是大的数值,情况就跟前面的一样了:

>>> a=4444
>>> b=4444
>>> a is b
False
>>> a==b
True