Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可

1 tup1 = ('physics', 'chemistry', 1997, 2000)
2 tup2 = (1, 2, 3, 4, 5 )
3 tup3 = "a", "b", "c", "d"
4 组中只包含一个元素时,需要在元素后面添加逗号
5 tup1 = (50,)

元组和列表之间的转换

使用 list 函数 可以把 元组 转换成 列表

使用 tuple 函数 可以把 列表 转换成 元组

list(元组)
 1 >>> a = ['a','b']
 2 >>> n = [1,3,6]
 3 >>> x = [a,n]
 4 >>> print (type(x))
 5 <class 'list'>
 6 >>> new_x = tuple(x)
 7 >>> print(type(new_x))
 8 <class 'tuple'>
 9 #列表转换元组
10 >>> num = (1,3,6,9)
11 >>> print (type(num))
12 <class 'tuple'>
13 >>> list_num = list(num)
14 >>> print (type(list_num))
15 <class 'list'>
16 #元组转换列表

4、字典

 字典是一系列键-值对。每个键都与一个值相关联,你可以使用键来访问与之相关的值。与键值相关的值可以是数字,字符串,列表或字典等

字典用放在花括号{}中的一系列键-值对表示

Python有两种方法可以创建字典,第一种是使用花括号,另一种是使用内建 函数dict

>>> info = {}
>>> info = dict()

Python可以在创建字典的时候初始化字典

>>> info = {"name" : 'cold'}
>>> info = dict(name = 'cold')       # 更优雅
>>> print(info)
{'name': 'cold'}

很明显第二种方法更加的优雅和减少一些特殊字符的输入,但是有种情况第二种不能胜任

>>> key = 'name'
>>> info = { key :'cold'}  # {'name':'cold'}
>>> info = dict(key = 'cold') # {'key': 'cold'}

明显第二种方法就会引发一个不容易找到的bug

使用元组作为字典的Key

>>> dict2 = {(20, 30):'good', 30:'bad'}
>>> print(dict2)
{(20, 30): 'good', 30: 'bad'}
#创建的字典中第一个 key 是元组,第二个 key 是整数值,这都是合法的
需要指出的是,元组可以作为 dict 的 key,但列表不能作为元组的 key。这是由于 dict 要求 key 必须是不可变类型,但列表是可变类型,因此列表不能作为元组的 key

在使用 dict() 函数创建字典时,可以传入多个列表或元组参数作为 key-value 对,每个列表或元组将被当成一个 key-value 对,因此这些列表或元组都只能包含两个元素。例如如下代码:

 1 >>> vegetables = [('celery', 1.58), ('brocoli', 1.29), ('lettuce', 2.19)]
 2 >>> dict3 = dict(vegetables)
 3 >>> print(dict3)
 4 {'celery': 1.58, 'brocoli': 1.29, 'lettuce': 2.19}
 5 ## 创建包含3组key-value对的字典
 6 >>> cars = [['BMW', 8.5], ['BENS', 8.3], ['AUDI', 7.9]]
 7 >>> dict4 = dict(cars)
 8 >>> print(dict4)
 9 {'BMW': 8.5, 'BENS': 8.3, 'AUDI': 7.9}
10 >>>
11 # 创建包含3组key-value对的字典
  • 创建字典
 1  >>> aline_0 = {'color': 'green','points': 5}
 2  >>> print(aline_0['color'])
 3 green
 4 #通过Key访问Value
 5 >>> aline_0 = {'color': 'green','points': 5}
 6 >>> print(aline_0['points'])
 7 5
 8 >>>
 9 #如果要为 dict 添加 key-value 对,只需为不存在的 key 赋值即可
10 scores = {'语文':89}
11 scores['数学'] = 93
12 scores['英语'] = 87
13 print(scores)
14 {'语文': 89, '数学': 93, '英语': 87}

如果要判断字典是否包含指定的 key,则可以使用 in 或 not in 运算符。需要指出的是,对于 dict 而言,in 或 not in 运算符都是基于 key 来判断的。例如如下代码:

>>> aline_0 = {'color': 'green','points': 5}
>>> print('red' in aline_0)
False
#判断aline_0是否包含名为'red'的key
>>> print('red' not in aline_0)
True
>>>

通过上面介绍可以看出,字典的 key 是它的关键。换个角度来看,字典的 key 就相当于它的索引,只不过这些索引不一定是整数类型,字典的 key 可以是任意不可变类型。

可以这样说,字典相当于索引是任意不可变类型的列表:而列表则相当于 key 只能是整数的字典。因此,如果程序中要使用的字典的 key 都是整数类型,则可考虑能否换成列表。

此外,还有一点需要指出,列表的索引总是从 0 开始、连续增大的;但字典的索引即使是整数类型,也不需要从 0 开始,而且不需要连续。因此,列表不允许对不存在的索引赋值:但字典则允许直接对不存在的 key 赋值,这样就会为字典增加一个 key-value 对

  • 添加键-值对
1 >>> aline_0 = {'color': 'green','points': 5}
2 >>> aline_0['x_position'] = 0
3 >>> aline_0['y_position'] = 23
4 >>> print(aline_0)
5 {'color': 'green', 'points': 5, 'x_position': 0, 'y_position': 23}
6 >>>
  • 修改字典中的值
>>> aline_0 = {'color': 'green','points': 5}
>>> aline_0['color'] = 'yellow'
>>> print(aline_0)
{'color': 'yellow', 'points': 5}
>>>
  • 删除键-值对
>>> aline_0 = {'color': 'green','points': 5}
>>> del aline_0['color']
>>> print(aline_0)
{'points': 5}
>>>

字典常用方法

字典由 dict 类代表,因此我们同样可使用 dir(dict) 来查看该类包含哪些方法。在交互式解释器中输入 dir(dict) 命令,将看到如下输出结果

>>> dir(dict)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

clear()方法 用于清空字典中所有的 key-value 对,对一个字典执行 clear() 方法之后,该字典就会变成一个空字典。例如如下代码:

1 >>> aline_0 = {'color': 'green','points': 5}
2 >>> print(aline_0)
3 {'color': 'green', 'points': 5}
4 >>> aline_0.clear()
5 >>> print(aline_0)
6 {}

get()方法

get() 方法其实就是根据 key 来获取 value,它相当于方括号语法的增强版,当使用方括号语法访问并不存在的 key 时,字典会引发 KeyError 错误;但如果使用 get() 方法访问不存在的 key,该方法会简单地返回 None,不会导致错误。例如如下代码

1 >>> aline_0 = {'color': 'green','points': 5}
2 >>> print(aline_0.get('color'))
3 green
4 >>> print(aline_0.get('red'))
5 None

update()方法

update() 方法可使用一个字典所包含的 key-value 对来更新己有的字典。在执行 update() 方法时,如果被更新的字典中己包含对应的 key-value 对,那么原 value 会被覆盖;如果被更新的字典中不包含对应的 key-value 对,则该 key-value 对被添加进去

例如如下代码

1 >>> aline_0 = {'color': 'green','points': 5}
2 >>> aline_0.update({'color': 'red','name': 'zhangsan'})
3 >>> print(aline_0)
4 {'color': 'red', 'points': 5, 'name': 'zhangsan'}
5 >>>

items()、keys()、values()

items()、keys()、values() 分别用于获取字典中的所有 key-value 对、所有 key、所有 value。这三个方法依次返回 dict_items、dict_keys 和 dict_values 对象,Python 不希望用户直接操作这几个方法,但可通过 list() 函数把它们转换成列表。如下代码示范了这三个方法的用法:

aline_0 = {'color': 'red','points': 5,'name': 'zhangsan'}
>>> print(aline_0)
{'color': 'red', 'points': 5, 'name': 'zhangsan'}
>>> ims = aline_0.items()
>>> print(type(ims))
# 获取字典所有的key-value对,返回一个dict_items对象
<class 'dict_items'>
>>> print(list(ims))
# 将dict_items转换成列表
[('color', 'red'), ('points', 5), ('name', 'zhangsan')]
>>>
# 访问第2个key-value对
>>> print(list(ims)[1])
('points', 5)
>>>

从上面代码可以看出,程序调用字典的 items()、keys()、values() 方法之后,都需要调用 list() 函数将它们转换为列表,这样即可把这三个方法的返回值转换为列表

 获取Key,value并循环

1 info = dict(name='百度',blog = 'baidu.com')
2 for key,value in info.items():
3     print(key,':',value)
4 >>>>
5 name : 百度
6 blog : baidu.com
  • popitem()方法

popitem() 方法用于随机弹出字典中的一个 key-value 对

此处的随机其实是假的,正如列表的 pop() 方法总是弹出列表中最后一个元素,实际上字典的 popitem() 其实也是弹出字典中最后一个 key-value 对。由于字典存储 key-value 对的顺序是不可知的,因此开发者感觉字典的 popitem() 方法是“随机”弹出的,但实际上字典的 popitem() 方法总是弹出底层存储的最后一个 key-value 对
>>> cars = {'语文': 80,'数学': 90,'英语': 86}
>>> print(cars)
{'语文': 80, '数学': 90, '英语': 86}
>>> print(cars.popitem()) # 弹出字典底层存储的最后一个key-value对
('英语', 86)
>>> print(cars)
{'语文': 80, '数学': 90}
>>>
由于实际上 popitem 弹出的就是一个元组,因此程序完全可以通过序列解包的方式用两个变量分别接收 key 和 value。例如如下代码:
>>> k,v = cars.popitem()
>>> print(k,v)
数学 90
>>>

使用词典传入真是值

temp = "语文:%(name_1)d, 数学:%(name_2)d, 出版社是:%(name_3)d"
book = {'name_1':80, 'name_2': 99, 'name_3': 88}
print(temp % book)
>>>>>
语文:80, 数学:99, 出版社是:88
# 使用字典为字符串模板中的key传入值

六、数据运算
算术运算符也即数学运算符,用来对数字进行数学运算,比如加减乘除。下表列出了 Python 支持所有基本算术运算符

 + 加法运算

a = 10
b = 20
sum = a + b
x = 2.5
y = 7.12
sum2 = x + y
print("sum=%d,sum2=%.2f" % (sum,sum2))
>>>
sum=30,sum2=9.62

- 减法运算符

>>> n  = 45
>>> m = -n
>>> x = -34
>>> y = -x
>>> print(m,";",y)
-45 ; 34
>>>

*乘法运算符

>>> n = 2*3
>>> f = 2.2*3
>>> print(n ,";",f)
6 ; 6.6000000000000005
>>>

/和//除法运算符

Python 支持///两个除法运算符,但它们之间是有区别的:

  • /表示普通除法,使用它计算出来的结果和数学中的计算结果相同。
  • //表示整除,只保留结果的整数部分,舍弃小数部分;注意是直接丢掉小数部分,而不是四舍五入。
>>> print("25/5=",25/5)
25/5= 5.0
>>>
>>> print("23/5=",23/5)
23/5= 4.6
>>> print("23//5=",23//5)
23//5= 4
>>>

从运行结果可以发现:

  • /的计算结果总是小数,不管是否能除尽,也不管参与运算的是整数还是小数。
  • 当有小数参与运算时,//结果才是小数,否则就是整数。

%求余运算符

>>> print("15%-6=",15%-6)
15%-6= -3
>>> print("-15%6=",-15%6)
-15%6= 3
>>> print("15.5%6=",15.5%6)
15.5%6= 3.5
>>>
#从运行结果可以发现两点:
只有当第二个数字是负数时,求余的结果才是负数。换句话说,求余结果的正负和第一个数字没有关系,只由第二个数字决定。
%两边的数字都是整数时,求余的结果也是整数;但是只要有一个数字是小数,求余的结果就是小数

**次方(乘方)运算符

 ** 运算符用来求一个 x 的 y 次方,也即次方(乘方)运算符。由于开方是次方的逆运算,所以也可以使用 ** 运算符间接地实现开方运算

>>> print("3**4=",3**4)
3**4= 81
# 次方运算

>>> print("2**(1/2)=",2**(1/2))
2**(1/2)= 1.4142135623730951
>>>
# 开方运算

2、比较运算

== 和 is 的区别

初学 Python,大家可能对 is 比较陌生,很多人会误将它和 == 的功能混为一谈,但其实 is 与 == 有本质上的区别,完全不是一码事儿。

== 用来比较两个变量的值是否相等,而 is 则用来比对两个变量引用的是否是同一个对象,例如

import time
t1 = time.gmtime()
t2 = time.gmtime()
print(t1==t2)
print(t1 is t2)
>>>>
True
False

time 模块的 gmtime() 方法用来获取当前的系统时间,精确到秒级,因为程序运行非常快,所以 t1 和 t1 得到的时间是一样的。== 用来判断 t1 和 t2 的值是否相等,所以返回 True。

虽然 t1 和 t2 的值相等,但它们是两个不同的对象(每次调用 gmtime() 都返回不同的对象),所以t1 is t2返回 False。这就好像两个双胞胎姐妹,虽然她们的外貌是一样的,但它们是两个人。

那么,如何判断两个对象是否相同呢?答案是判断两个对象的内存地址。如果内存地址相同,说明两个对象使用的是同一块内存,当然就是同一个对象了;这就像两个名字使用了同一个身体,当然就是同一个人了

3、赋值运算

n1 = 100
f1 = 25.5
n1 -= 80  #等价于 n1=n1-80
f1 *= n1 - 10 #等价于 f1=f1*( n1 - 10 )
print("n1=%d" % n1)
print("f1=%.2f" % f1)
>>>>>
运行结果为:
n1=20
f1=255.00

通常情况下,只要能使用扩展后的赋值运算符,都推荐使用这种赋值运算符。

但是请注意,这种赋值运算符只能针对已经存在的变量赋值,因为赋值过程中需要变量本身参与运算,如果变量没有提前定义,它的值就是未知的,无法参与运算。例如,下面的写法就是错误的:

n += 10

该表达式等价于 n = n + 10,n 没有提前定义,所以它不能参与加法运算

4、逻辑运算符

逻辑运算符一般和关系运算符结合使用,例如:

14>6 and 45.6 < 90

14>6 结果为 True,成立,45.6<90 结果为 False,不成立,所以整个表达式的结果为 False,也即不成立

age = int(input('请输入你的年龄:'))
height = int(input('请输入你的身高:'))
if age>=18 and age<=30 and height >=170 and height <=185:
    print("恭喜你,符合报考飞行员的条件")
else:
    print("抱歉,你不符合")

运行结果
请输入年龄:23↙
请输入身高:178↙
恭喜,你符合报考飞行员的条件

Python 逻辑运算符可以用来操作任何类型的表达式,不管表达式是不是 bool 类型;同时,逻辑运算的结果也不一定是 bool 类型,它也可以是任意类型。请看下面的例子

>>> print(100 and 200)
200
>>> print("" or "Neal")
Neal

逻辑运算符的本质

在 Python 中,and 和 or 不一定会计算右边表达式的值,有时候只计算左边表达式的值就能得到最终结果。

另外,and 和 or 运算符会将其中一个表达式的值作为最终结果,而不是将 True 或者 False 作为最终结果。

以上两点极其重要,了解这两点不会让你在使用逻辑运算的过程中产生疑惑

对于 and 运算符,两边的值都为真时最终结果才为真,但是只要其中有一个值为假,那么最终结果就是假,所以 Python 按照下面的规则执行 and 运算:

  • 如果左边表达式的值为假,那么就不用计算右边表达式的值了,因为不管右边表达式的值是什么,都不会影响最终结果,最终结果都是假,此时 and 会把左边表达式的值作为最终结果。
  • 如果左边表达式的值为真,那么最终值是不能确定的,and 会继续计算右边表达式的值,并将右边表达式的值作为最终结果。


对于 or 运算符,情况是类似的,两边的值都为假时最终结果才为假,只要其中有一个值为真,那么最终结果就是真,所以 Python 按照下面的规则执行 or 运算:

    • 如果左边表达式的值为真,那么就不用计算右边表达式的值了,因为不管右边表达式的值是什么,都不会影响最终结果,最终结果都是真,此时 or 会把左边表达式的值作为最终结果。
    • 如果左边表达式的值为假,那么最终值是不能确定的,or 会继续计算右边表达式的值,并将右边表达式的值作为最终结果
 
5、位运算符
 Python 位运算符只能用来操作整数类型,它按照整数在内存中的二进制形式进行计算

 

 1、首先了解以下二进制转换十进制

 

 2.第二种

  00000001    1

  00000011    3

  00000111    7

  00001111    15

  00011111    31

  00111111    63

  01111111    127

 

 

 举个例子:11101011

  可分为:

      11100000=224

      00001000=8

      00000011=3

需要记住2的0-10次方值

2^7  2^6  2^5  2^4  2^3  2^2  2^1  2^0

128  64  32   16  8    4   2    1

============================================

0-7次方的总和为255

1、& 按位与运算符

按位与运算符&的运算规则是:只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0。例如1&1为 1,0&0为 0,1&0也为 0,这和逻辑运算符&&非常类似

 例如:9&5可以转换成如下的运算:

  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (9 在内存中的存储)
& 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101  (5 在内存中的存储)
-----------------------------------------------------------------------------------
  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001  (1 在内存中的存储)

&
运算符会对参与运算的两个整数的所有二进制位进行&运算,9&5的结果为 1

又如,-9&5可以转换成如下的运算:
  1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111  (-9 在内存中的存储)
& 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101  (5 在内存中的存储)
-----------------------------------------------------------------------------------
  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101  (5 在内存中的存储)
-9&5的结果是 5

再强调一遍,&运算符操作的是数据在内存中存储的原始二进制位,而不是数据本身的二进制形式;其他位运算符也一样。以-9&5为例,-9 的在内存中的存储和 -9 的二进制形式截然不同:

1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111 (-9 在内存中的存储)
-0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (-9 的二进制形式,前面多余的0可以抹掉)
2、| 按位或运算符

按位或运算符|的运算规则是:两个二进制位有一个为 1 时,结果就为 1,两个都为 0 时结果才为 0。例如1|1为 1,0|0为0,1|0 为1,这和逻辑运算中的||非常类似

例如,9 | 5可以转换成如下的运算:
  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (9 在内存中的存储)
| 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101  (5 在内存中的存储)
-----------------------------------------------------------------------------------
  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1101  (13 在内存中的存储)
9 | 5的结果为 13

3、^按位异或运算符

按位异或运算^的运算规则是:参与运算的两个二进制位不同时,结果为 1,相同时结果为 0。例如0^1为 1,0^0为 0,1^1为 0



例如,9 ^ 5可以转换成如下的运算:
  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (9 在内存中的存储)
^ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101  (5 在内存中的存储)
-----------------------------------------------------------------------------------
  0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1100  (12 在内存中的存储)
9 ^ 5的结果为 12

4、~按位取反运算符
按位取反运算符~为单目运算符(只有一个操作数),右结合性,作用是对参与运算的二进制位取反。例如~1为0,~0为1,这和逻辑运算中的!非常类似
例如,~9可以转换为如下的运算:
~ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (9 在内存中的存储)
-----------------------------------------------------------------------------------
  1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0110  (-10 在内存中的存储)
所以~9的结果为 -10

5、左移运算符

Python 左移运算符<<用来把操作数的各个二进制位全部左移若干位,高位丢弃,低位补 0
例如,9<<3可以转换为如下的运算:
<< 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (9 在内存中的存储)
-----------------------------------------------------------------------------------
   0000 0000 -- 0000 0000 -- 0000 0000 -- 0100 1000  (72 在内存中的存储)
所以9<<3的结果为 72

6、>>右移运算符
Python 右移运算符>>用来把操作数的各个二进制位全部右移若干位,低位丢弃,高位补 0 或 1。如果数据的最高位是 0,那么就补 0;如果最高位是 1,那么就补 1
例如,9>>3可以转换为如下的运算:
>> 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001  (9 在内存中的存储)
-----------------------------------------------------------------------------------
   0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001  (1 在内存中的存储)
所以9>>3的结果为 1

七、三目运算符(三元运算符)

我们从一个具体的例子切入本节内容。假设现在有两个数字,我们希望获得其中较大的一个,那么可以使用 if else 语句,例如:
  1. if a>b:
  2. max = a;
  3. else:
  4. max = b;
但是 Python 提供了一种更加简洁的写法,如下所示:

max = a if a>b else b

这是一种类似于其它编程语言中三目运算符? :的写法。Python 是一种极简主义的编程语言,它没有引入? :这个新的运算符,而是使用已有的 if else 关键字来实现相同的功能。

使用 if else 实现三目运算符(条件运算符)的格式如下:

exp1 if contion else exp2


condition 是判断条件,exp1 和 exp2 是两个表达式。如果 condition 成立(结果为真),就执行 exp1,并把 exp1 的结果作为整个表达式的结果;如果 condition 不成立(结果为假),就执行 exp2,并把 exp2 的结果作为整个表达式的结果。

前面的语句max = a if a>b else b的含义是:
    • 如果 a>b 成立,就把 a 作为整个表达式的值,并赋给变量 max;
    • 如果 a> b 不成立,就把 b 作为整个表达式的值,并赋给变量 max

三目运算符的嵌套

Python 三目运算符支持嵌套,如此可以构成更加复杂的表达式。在嵌套时需要注意 if 和 else 的配对,例如:

a if a>b else c if c>d else d

应该理解为:

a if a>b else ( c if c>d else d )


【实例】使用 Python 三目运算符判断两个数字的关系:

  1. a = int( input("Input a: ") )
  2. b = int( input("Input b: ") )
  3. print("a大于b") if a>b else ( print("a小于b") if a<b else print("a等于b") )

可能的运行结果:

Input a: 45↙
Input b: 100↙
a小于b

该程序是一个嵌套的三目运算符。程序先对 a>b 求值,如果该表达式为 True,程序就返回执行第一个表达式 print("a大于b"),否则将继续执行 else 后面的内容,也就是:

( print("a小于b") if a<b else print("a等于b") )

进入该表达式后,先判断 a<b 是否成立,如果 a<b 的结果为 True,将执行 print("a小于b"),否则执行 print("a等于b")。

八、Python 运算符优先级

Python 支持几十种运算符,被划分成将近二十个优先级,有的运算符优先级不同,有的运算符优先级相同

结果表1中的运算符优先级,我们尝试分析下面表达式的结果:

4+4<<2

+的优先级是 12,<<的优先级是 11,+的优先级高于<<,所以先执行 4+4,得到结果 8,再执行 8<<2,得到结果 32,这也是整个表达式的最终结果。

像这种不好确定优先级的表达式,我们可以给子表达式加上( ),也就是写成下面的样子:

(4+4) << 2

这样看起来就一目了然了,不容易引起误解。

当然,我们也可以使用( )改变程序的执行顺序,比如:

4+(4<<2)

则先执行 4<<2,得到结果 16,再执行 4+16,得到结果20。

虽然 Python 运算符存在优先级的关系,但我不推荐过度依赖运算符的优先级,这会导致程序的可读性降低。因此,我建议读者:

    • 不要把一个表达式写得过于复杂,如果一个表达式过于复杂,可以尝试把它拆分来书写。
    • 不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,应尽量使用( )来控制表达式的执行顺序

Python 运算符结核性

所谓结合性,就是当一个表达式中出现多个优先级相同的运算符时,先执行哪个运算符:先执行左边的叫左结合性,先执行右边的叫右结合性。

例如对于表达式对于100 / 25 * 16/*的优先级相同,应该先执行哪一个呢?这个时候就不能只依赖运算符优先级决定了,还要参考运算符的结合性。/*都具有左结合性,因此先执行左边的除法,再执行右边的乘法,最终结果是 64。

Python 中大部分运算符都具有左结合性,也就是从左到右执行;只有单目运算符(例如 not 逻辑非运算符)、赋值运算符和三目运算符例外,它们具有右结合性,也就是从右向左执行。表 1 中列出了所有 Python 运算符的结合性

当一个表达式中出现多个运算符时,Python 会先比较各个运算符的优先级,按照优先级从高到低的顺序依次执行;当遇到优先级相同的运算符时,再根据结合性决定先执行哪个运算符:如果是左结合性就先执行左边的运算符,如果是右结合性就先执行右边的运算符