Python3入门到精通——变量与运算符

作者: Daniel Meng

GitHub: LibertyDream

博客:明月轩

本系列教程采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议

变量

变量即对某种类型数据实体的抽象,或者说给某个类型数据的实体起的名字。基本操作方式是var = xxx=是赋值操作,注意,python里面不需要像Java一样的变量声明

In [2]:
[1,2,3,4,5,6]*3+[1,2,3]+[1,2,3,4,5,6]
Out[2]:
[1,
 2,
 3,
 4,
 5,
 6,
 1,
 2,
 3,
 4,
 5,
 6,
 1,
 2,
 3,
 4,
 5,
 6,
 1,
 2,
 3,
 1,
 2,
 3,
 4,
 5,
 6]
In [3]:
A = [1,2,3,4,5,6]
print(A) # 打印A的值
[1, 2, 3, 4, 5, 6]
In [4]:
B = [1,2,3]
A * 3 + B + A
Out[4]:
[1,
 2,
 3,
 4,
 5,
 6,
 1,
 2,
 3,
 4,
 5,
 6,
 1,
 2,
 3,
 4,
 5,
 6,
 1,
 2,
 3,
 1,
 2,
 3,
 4,
 5,
 6]

命名规范

变量可以方便我们的操作。变量起名要规范

  • python规定变量可以以字母、下划线开头,由字母、数字、下划线组成
In [5]:
0a = 2
  File "<ipython-input-5-8998d3cd4a9b>", line 1
    0a = 2
     ^
SyntaxError: invalid syntax
In [6]:
a2 = 'f'
In [7]:
_2ab = '1'
  • python识别大小写,A与a不同
In [8]:
b # 没定义过变量b,报错
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-8-89e6c98d9288> in <module>()
----> 1 b

NameError: name 'b' is not defined
In [9]:
B
Out[9]:
[1, 2, 3]
  • python是弱类型语言,同一变量没有类型限制
In [10]:
a = '1'
In [11]:
a = 1
In [12]:
a = (1,2,3)
In [13]:
a = {1,2,3}
  • 系统保留关键字不能当做变量名
In [14]:
None = 'None'
  File "<ipython-input-14-278722683e31>", line 1
    None = 'None'
                 ^
SyntaxError: can't assign to keyword

值类型与引用类型

int、str、tuple是值类型,是不可变的,每次赋值都会开辟新的空间进行存储。list、set、dict是引用类型,每个变量类似于一个“指针”,指向一个固定位置,修改一个会影响另一个。

In [19]:
a = {1,2,3}
b = a
a = 3

print(b)
{1, 2, 3}
In [20]:
print(a)
3
In [21]:
a = [1,2,3,4,5]
b = a
a[0] = '1'

print(a)
['1', 2, 3, 4, 5]
In [22]:
print(b)
['1', 2, 3, 4, 5]

进一步说明值类型不可变,测试一下str

我们自行命名的变量都保存在内存当中,函数id()用于显示某个变量在内存中的地址

In [24]:
a = 'hello'

id(a)
Out[24]:
2825122969896
In [25]:
a = a + 'python'
id(a)
Out[25]:
2825122786992
In [26]:
'python'[0]
Out[26]:
'p'
In [27]:
'python'[0] = 'm' # 尝试给字符串赋值
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-27-adf5bda09f7f> in <module>()
----> 1 'python'[0] = 'm' # 尝试给字符串赋值

TypeError: 'str' object does not support item assignment

元组不可变,所以没有追加元素等操作。list等可变,所以能添加、删除、修改。

In [28]:
a = (1,2,3,[1,2,4])
a[2]
Out[28]:
3
In [29]:
a[3][2]
Out[29]:
4
In [30]:
a = (1,2,3,[1,2,['a','b','c']])

a[3][2][1]
Out[30]:
'b'
In [31]:
a[2] = '3'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-31-81f59a93cf75> in <module>()
----> 1 a[2] = '3'

TypeError: 'tuple' object does not support item assignment
In [32]:
a[3][2] = '4'

print(a)
(1, 2, 3, [1, 2, '4'])

这一组合例子中,因元组不可变而list可变,所以a[3]存储的是一个不变的地址,地址里的内容可变

运算符

operators

算数运算符

包括常见的+,-,*,/,%等,幂运算python采用**来实现。其中要注意+-*在处理某些数据结构时的含义,如拼接,差集,复制等

In [34]:
'hello' + ' world'
Out[34]:
'hello world'
In [35]:
[1,2,3] * 3
Out[35]:
[1, 2, 3, 1, 2, 3, 1, 2, 3]
In [36]:
3 - 1
Out[36]:
2
In [37]:
3 / 2
Out[37]:
1.5
In [38]:
3 // 2
Out[38]:
1
In [39]:
5 % 2
Out[39]:
1
In [40]:
2 ** 2
Out[40]:
4

赋值运算符

顾名思义,通过一些简单的运算(甚至没有),将数据赋予某个变量,操作的核心一定是落在赋值上

In [41]:
c = 1
c = c + 1

print(c)
2
In [42]:
c += 1

print(c)
3
In [43]:
b = 2
a = 3
b += a

print(b)
5
In [44]:
b -= a

print(b)
2
In [45]:
b *= a

print(b)
6

关系运算符

用于确定两个元素大小关系的运算符号。python并不是只有数字类型才能做大小比较,不同类型数据不能直接通过运算符比较大小。

In [60]:
'a' > 36
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-60-04b135dba783> in <module>()
----> 1 'a' > 36

TypeError: '>' not supported between instances of 'str' and 'int'
In [46]:
1 > 1
Out[46]:
False
In [47]:
1 >= 1
Out[47]:
True
In [48]:
a = 1
b = 2

a != b
Out[48]:
True

单个字符比较ASCII码,字符串比较大小是对每一个对位字符进行大小比较。关系运算的重点是运算完成后返回的Boolean值

In [49]:
'a' > 'b'
Out[49]:
False
In [50]:
'abc' < 'abd'
Out[50]:
True

列表间的比较按照下列顺序进行:

  1. 将两个列表对应的元组进行比较
  2. 如果比较元素是同类型的,则比较其值,返回结果。
  3. 如果有一个列表首先到达末尾,则另一个长一点的列表“大”。
  4. 如果我们用尽了两个列表的元素而且所有的元素都是相等的,那么返回0。
In [55]:
[1,2,3] > [1,2]
Out[55]:
True
In [61]:
[1,2,3] > [1,2,3]
Out[61]:
False
In [57]:
[1,2,3] < [1,2,4]  # 逐个比较元素,有一个为真即为真
Out[57]:
True
In [53]:
(1,2,3) > (1,1,4)
Out[53]:
True

逻辑运算符

特点:操作布尔值,返回布尔值。操作只有三种:与、或、非

In [62]:
True and True
Out[62]:
True
In [63]:
True and False
Out[63]:
False
In [64]:
True or False
Out[64]:
True
In [65]:
False or False
Out[65]:
False
In [66]:
not False
Out[66]:
True

对于非布尔类型的判定方法:

  • 对于int、float等数值类型,非0表示True,0表示False
  • 对于字符串,非空表示True,空表示False
  • 对于“组”,list、set等来说。非空表示True,空表示False
In [67]:
1 and 1
Out[67]:
1
In [68]:
'a' and 'b'
Out[68]:
'b'
In [69]:
'a' or 'b'
Out[69]:
'a'
In [70]:
not 'a'
Out[70]:
False
In [71]:
not []
Out[71]:
True
In [72]:
not [1,2]
Out[72]:
False

not操作返回的是显性的True和False。但andor不一定

In [73]:
not []
Out[73]:
True
In [74]:
not [1,2]
Out[74]:
False
In [75]:
[1] or []
Out[75]:
[1]
In [76]:
1 and 0
Out[76]:
0

andor结果显示遵循“扫描原则”,若当前位已能决定结果则返回当前位,否则继续

In [77]:
0 and 1
Out[77]:
0
In [78]:
1 and 2
Out[78]:
2
In [79]:
2 and 1
Out[79]:
1
In [80]:
0 or 1
Out[80]:
1
In [81]:
1 or 0
Out[81]:
1
In [82]:
1 or 2
Out[82]:
1

成员运算符

包括innot in两个操作,用于判断成员是否属于某一个组

In [84]:
a = 1

a in [1,2,3,4,5]
Out[84]:
True
In [85]:
b = 6

b in [1,2,3,4]
Out[85]:
False
In [86]:
b not in (1,2,3,4,5)
Out[86]:
True
In [87]:
b not in {1,2,3,4,5}
Out[87]:
True

对于字典(dict)类型,innot in操作比对的是key键

In [88]:
b = 'a'

b in {'c':1}
Out[88]:
False
In [89]:
b = 1

b in {'c':1}
Out[89]:
False
In [90]:
b = 'c'

b in {'c':1}
Out[90]:
True

身份运算符

包括isnot is。用于判断符号左右两端是否“身份”相同

In [91]:
a = 1
b = 1

a is b
Out[91]:
True
In [92]:
a = 2

a is b
Out[92]:
False
In [93]:
a = 'hello'
b = 'world'

a is b
Out[93]:
False

初看上述这些判别会误以为他和关系运算符(==)相同。但看下例会发现不同

In [94]:
a = 1
b = 1.0

a is b
Out[94]:
False
In [95]:
a == b
Out[95]:
True

身份运算符所谓“身份”,其实核对的是内存地址是否相同,不关心值是否相同,简单粗暴的说就是比对id()值是否相同

In [96]:
a = 1
b = 1
In [97]:
id(a)
Out[97]:
1542221280
In [98]:
id(b)
Out[98]:
1542221280
In [99]:
a is b
Out[99]:
True
In [100]:
a == b
Out[100]:
True
In [101]:
b = 1.0

id(b)
Out[101]:
2825122000088
In [102]:
a is b
Out[102]:
False
In [103]:
a == b
Out[103]:
True

对于set、tuple等也同样可以使用身份运算符

In [104]:
a = {1,2,3}
b = {2,1,3}
In [105]:
a is b
Out[105]:
False
In [106]:
a == b
Out[106]:
True
In [107]:
a = (1,2,3)
b = (2,1,3)
In [108]:
a is b
Out[108]:
False
In [109]:
a == b
Out[109]:
False

因为集合的无序性所以关系比较是相同的,元组无此特性故而关系比较结果为False。同时因为每一个的内存地址都是特异的,所以他们都是身份独立的,互不相同。

对象三大特征

python中一切皆对象

  • 值 value,使用==判定
  • 身份id(),使用is判定
  • 类型type(),使用isinstance判定

值和身份判断上文已讲,这里说明一下类型判断

In [110]:
a = 'hello'

type(a) == int
Out[110]:
False
In [111]:
type(a) == str
Out[111]:
True
In [112]:
isinstance(a, str)
Out[112]:
True
In [113]:
isinstance(a, int)
Out[113]:
False
In [114]:
isinstance(a, (int, str, float))
Out[114]:
True
In [115]:
isinstance(a, (int,float))
Out[115]:
False

类型判断就是为了判定类型,可以用type(x)==bb方式,但更推荐isinstance(x,(aa,bb,...))方法,二者都返回布尔值。但后者可以判断x的子类是否属于某一种类型,而type()不行

位运算符

主要以按位与&和按位或|为代表,将数字当做二进制然后以每一位为独立单位进行运算(位运算)。

In [116]:
a = 2
b = 3

a & b
Out[116]:
2
In [117]:
a = 2
b = 3

a | b
Out[117]:
3

这里的与和或操作同中学数学,&操作中当有一个为0时,结果为0。|操作中当有一个为1时,结果为1

~(非)按位取反,这一操作涉及到二进制补码。计算机中负数表示方法是符号位+补码,获取其表示数需要摘出符号位(0为正,1为负),剩余部分取反加一。

>><<是对每一位进行移位运算,规则是向右移动时,高位补符号位,向左移动时,低位补0

In [118]:
a = 1

~a
Out[118]:
-2
In [119]:
a << 1
Out[119]:
2
In [120]:
a = 3

a >> 1
Out[120]:
1