计算机的最原始的功能莫过于运算,实际上无论多么高级复杂的程序,最终都要转化成二进制来进行运算后反馈给我们所需要的信息。这一章,我们会依次来展示我们所学数据类型的各种运算。
数学运算
我们最基本的运算,这一点毫无疑问。从小学开始接触数学我们就开始学习各种运算,在这里我们就四则运算说起。
- 加法'+' , 减法'-',乘法'*'
Python交互式可以自行运算:
>>> 5 + 3
8
>>> 5 - 3
2
>>> 5 * 3
15
我仍然习惯在符号两边保留空格以使得代码更加清晰。
变量当然也可以进行
>>> a = 5
>>> b = 3
>>> a + b
8
>>> a - b
2
>>> a * b
15
有一点需要注意,两个不同类型的数据运算,其结果为"更为复杂”的类型
>>> 5 + 3.0
8.0
>>> 5 + (1+2j)
(6+2j)
- 除法'/'
为什么要把除非特意拿出来?因为它确实是比较特殊
>>> 5 / 3
1
>>> 5 / 3.0
1.6666666666666667
很简单, 两个整型的除法运算,只会保留商,而会把余数舍去。如果想要得到近似的准确答案,则必须改用浮点数
- 其余运算符, 求余'%', 乘方'**'
直接看例子:
>>> 5 % 3
2
>>> 2 ** 2
4
其余的数学运算符号,基本要使用到函数,至于这个问题,我们目前先不谈,有兴趣的搜索Python math来看。
- 赋值运算符
运算符 | 描述 | 示例 |
---|---|---|
= | 简单的赋值运算符,赋值从右侧操作数左侧操作数 | c = a + b将指定的值 a + b 赋值到 c |
+= | 加法和赋值操作符,它增加了右操作数左操作数和结果赋给左操作数 | c += a 相当于 c = c + a |
-= | 减法和赋值操作符,它减去右边的操作数从左边操作数,并将结果赋给左操作数 | c -= a 相当于 c = c - a |
*= | 乘法和赋值操作符,它乘以右边的操作数与左操作数,并将结果赋给左操作数 | c *= a 相当于 c = c * a |
/= | 除法和赋值操作符,它把左操作数与正确的操作数,并将结果赋给左操作数 | c /= a 相当于= c / a |
%= | 求模和赋值操作符,它需要使用两个操作数的模量和分配结果左操作数 | c %= a 相当于 c = c % a |
**= | 指数和赋值运算符,执行指数计算操作符和赋值给左操作数 | 相当于 c = c ** a |
5.注意浮点数!
由于计算机在运算的时候,本质上需要转换成二进制,但是计算机的位数是有限的,不会转换的那么精确...
>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1 * 0.2
0.020000000000000004
>>> 5 % 4.8
0.20000000000000018
如果需要精密计算,则要使用'decimal', 目前我们先不去碰它。
字符串简单运算
字符串简单元算,只有两个符号, 加法'+', 乘法'*'
加法是简答的连接两个字符串, 乘法是倍数重复字符串
>>> 'litte' + 'apple'
'litteapple'
>>> 'abc' * 5
'abcabcabcabcabc'
减法和除法在字符串运算中无法实现,主要是因为不确定性。
字符串的切片运算
这不是我们熟悉的运算,但是这确是python中一个非常重要的运算。
在学习切片运算之前,我们必须要搞清楚字符串的排序。字符串的本义是字符的“串”, 是一系列字符按顺序排起来,只不过字符串的排序不是从1开始,二是从0开始。我们称序号叫做'索引'。
比如'cat', 字符'c'的序号是0而不是1, 相应的'a'对应1,而't'对应2, 由此可见,字符串的序号是从0开始,到n-1(n是字符的个数)结束。这一点非常重要,以后学习的复杂的排序类型,也面临同样的问题。
索引通过'[ ]'中加数字来表示:
>>> text = 'apple tree'
>>> text[0]
'a'
>>> text[1]
'p'
>>> text[5]
' '
>>> text[9]
'e'
>>> text[10]
Traceback (most recent call last):
File "<pyshell#81>", line 1, in <module>
text[10]
IndexError: string index out of range
>>> text[-1]
'e'
>>> text[-2]
'e'
>>> text[-3]
'r'
>>> text[-10]
'a'
>>> text[-11]
Traceback (most recent call last):
File "<pyshell#86>", line 1, in <module>
text[-11]
IndexError: string index out of range
我们可以看到,变量text包含了9个字母个1个空格,共10个字符,索引从[0]排到了[9], 而[10]则越界,索引的上限是n-1。所以也可以逆向取值,[-0]是没有意义的,那么从[-1]开始, [-10]结束,所以逆向的上限是[-n]。
Pyhon的切片运算,换句话说,就是从字符串中“切”出一部分来,形成一个子字符串,运算符是'[:]'。刚才我们的索引,可以看成是最小的切片,即切出来一个字符。
>>> text = 'apple tree'
>>> GetOneCha = text[0]
'a'
切片运算符中冒号前后分别是切片的开始索引和结束索引
>>> text = 'apple tree'
>>> GetSomeCha1 = text[0:2]
>>> GetSomeCha1
'ap'
注意到了什么没有?我们结束索引是2,但是'ap'两个字符分是[0]和[1],它意味着结束的索引并不包含在内。
如果是从字符串开头开始取值,可以省略开始索引。
>>> GetSomeCha2 = text[:2]
>>> GetSomeCha2
'ap'
取到结尾的怎么办,因为结束字符不会包含在内,则不能用[9]或者[-1]来取,我们可以像开头那样省略它
>>> GetSomeCha3 = text[6:9]
>>> GetSomeCha3
'tre'
>>> GetSomeCha4 = text[6:-1]
>>> GetSomeCha4
'tre'
>>> GetSomeCha5 = text[6:]
>>> GetSomeCha5
'tree'
自然的,切选整个字符串则可应当前后索引都省略
>>> GetSomeCha6 = text[:]
>>> GetSomeCha6
'apple tree'
有时候我们会看到这样的切片[1:8:2], 第二个冒号后的是步长,表示每次截取的跨度,2表示每间隔一个字符选取一个。
>>> GetSomeCha7 = text[1:8:2]
>>> GetSomeCha7
'pl r'
[1]表示从字母'p'开始,到字母'r'([7],不包含[8])结束,每隔一个截取,则应该取[1] [3] [5] [7], 相应的是'p', 'l', ' '(空格), 'r'。
布尔运算符
布尔运算,实际上指的是"是"与“非”,“对”与"错”,“真”与“假”的运算,即结果是布尔型,Ture
和False
的运算。
如果表达式结果为真,我们得到的是True
,否则为False
。
以下是简单的比较操作符:
运算符 | 描述 | 示例 |
---|---|---|
== | 检查,两个操作数的值是否相等,如果是则条件变为真。 | (2 == 5) 为 False |
!= | 检查两个操作数的值是否相等,如果值不相等,则条件变为真。 | (2 != 5) 为 True |
> | 检查左操作数的值是否大于右操作数的值,如果是,则条件成立。 | (2 > 5) 为 False |
< | 检查左操作数的值是否小于右操作数的值,如果是,则条件成立。 | (2 < 5) 为 True. |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件成立。 | (2 >= 5) 为 False |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件成立。 | (2 <= 5) 为 True |
以下是逻辑操作符
运算符 | 描述 | 示例 |
---|---|---|
and | 所谓逻辑'与'运算符。如果两个操作数都是真的,那么则条件成立。 | 两者都为True时,运算结果为 True |
or | 所谓逻辑'或‘’运算符。如果有两个操作数都是非零然后再条件变为真。 | 两者任何一者为True时 , 运算结果为True |
not | 所谓逻辑'非'运算符。用于反转操作数的逻辑状态。如果一个条件为真,则逻辑非运算符将返回False。 | not True == False not False = True |
以下是成员运算符:
运算符 | 描述 | 示例 |
---|---|---|
in | 表达式为a in b , 在'b'中查找'a',如果找到则为True,反之False |
'a' in 'apple', 运算结果为 True |
not in | 表达式为a not in b , 在'b'中查找'a',如果找到则为True,反之False |
't' not in 'apple', 运算结果为 True |
以下是标识运算符
运算符 | 描述 | 示例 |
---|---|---|
is | 表达式为a is b , 两者是否指向相同的变量,如果是,结果为True反之False |
a =5, b = 5, a is b 结果为True |
not is | 表达式为a not is b , 两者是否指向不同的变量,如果是,结果为True反之False |
a =5, b = 5, a is not b 结果为False |
注意:is和not is,不仅仅是数值相等,而且要求数据类型相等。从本质上来说,是要求变量在系统内存中的地址相等。我们可以使用内建函数id()来确定变量的内存地址:
>>> a = 1
>>> b = 1.0
>>> id(a)
20905160
>>> id(b)
34855912
>>> a is b
False
很显然,1 is 1.0 结果是False
用id()很简单就可以验证,不是赋值给变量,而是变量指向常量
>>> a = 1
>>> id(a)
1440968
>>> a = 'hello'
>>> id(a)
34419584
有一点需要注意,你输入以上例子得到的内存的地址很可能和我是不一样的,这个没关系。因为内存地址是随机分配的,只要我关掉Python,这个地址就会消失。
运算优先级
运算符号的结合,按下述表格明确运算顺序
运算符 | 描述 |
---|---|
( ) | 小括号,优先级最高,运算符没有中括号和大括号,如需要则采用小括号的嵌套 |
** | 幂(提高到指数) |
+ - | 补码,正负 |
* / % | 乘,除,取模 |
+ - | 加法和减法 |
<= < > >= | 比较运算符 |
== != | 等式运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 标识运算符 |
in not in | 成员运算符 |
not or and | 逻辑运算符 |
其他
运算符还有一些,对于初学者比较复杂和难以理解,我们暂时不去介绍,有兴趣的可以自行搜索学习。
关于小括号,如果表达式过于复杂,虽然优先级保证了可以正确运算,我们仍然建议使用括号以使得代码更加清晰,比如:
3 + 2 - 5 * (6**2) + (4 / 2)
练习
只有一个,本章的表格较多,讲表格的例子转换成代码操作一下,当然你也可以用自己的数据来验证。