python数学计算优先级_Python 运算符及表达式

1. 第四章 运算符与表达式

本章的主题是 Python 语言的内建运算符及表达式求值的优先级。

1.1. 数值操作

所有数值类型都提供下列运算:运算 描述

x + y 加

x - y 减

x * y 乘

x / y 常规除

x // y 地板除

x ** y 乘方 (xy )

x % y 取模 (x mod y )

-x 改变操作数的符号位

+x 什么也不做

~x ~x=-(x+1)

关于常规除 / 与地板除 //: 地板除在任何时候都会将小数部分舍为0,而常规除的行为依操作数的类型而有不同。

常规除 / : 整数除以整数时 / 与 // 除完全相同,商都会被舍去小数部分而返回一个整数。如7 / 4 的结果是 1,而不是1.75;

如果有一个操作数为浮点数,情形就不同了:

对于 / ,会返回一个双精度浮点数

对于 //,也会返回一个双精度浮点数,只不过小数部分被舍弃

取模操作返回 x/y 的余数,如7 % 4是3。对于浮点数,取模操作返回的是x - int(x / y ) * y。 对于复数,取模操作返回x - int((x / y ).real ) * y。

下列列出的位运算符只能用于整数或长整数:操作 描述

x x >> y 右移

x & y 按位与

x | y 按位或

x ^ y 按位异或 (exclusive or)

~x 按位翻转

这些都是相当原始的运算,操作的是操作数的每一个位。所有的操作数都假定是以二进制补码形式表示。对于长整数,按位运算符假定符号位可以被无限地向左扩展。

除了这些以外,下边这些内建函数支持所有的数值类型:函数 描述

abs(x ) 绝对值

divmod(x ,y ) 返回 (int(x / y ), x % y )

pow(x ,y [,modulo ]) 返回 (x ** y ) x % modulo

round(x ,[n]) 四舍五入,n为小数点位数

abs()函数返回一个数的绝对值。divmod()函数返回一个包含商和余数的元组。pow()函数可以用于代替 ** 运算,但它还支持三重取模运算(经常用于密码运算)。 round函数总是返回一个浮点数。Python的四舍五入规则不是银行家四舍五入规则,这一点请大家注意。

下列比较操作有标准的数学解释,返回一个布尔值True,或者False:运算符 描述

x x > y 大于

x == y 等于

x != y 不等于(与相同)

x >= y 大于等于

x

Python的比较运算可以连结在一起,如w

x z这个表达式也是合法的,(注意,这个表达式中 x 和 z 并没有比较操作)。不建议这样的写法,因为这会造成代码的阅读困难。

只可以对复数进行等于(==)及不等于(!=)比较,任何对复数进行其他比较的操作都会引发TypeError异常。

数值操作要求操作数必须是同一类型,若Python发现操作数类型不一致,就会自动进行类型的强制转换,转换规则如下:1.如果操作数中有一个是复数,另一个也将被转换为复数

2.如果操作数中有一个是浮点数,另一个将被转换为浮点数

3.如果操作数中有一个是长整数数,另一个将被转换为长整数数

4.如果以上都不符合,则这两个数字必然都是整数,不需进行强制转换。

1.2. 序列运算

序列支持以下操作:操作 描述

s + r 序列连接

s * n , n * s s的 n 次拷贝,n为整数

s % d 字符串格式化(仅字符串)

s[i] 索引

s[i :j ] 切片

x in s , x not in s 从属关系

for x in s : 迭代

len(s) 长度

min(s) 最小元素

max(s) 最大元素

+ 运算符将两个相同类型的序列连结成一个。 s * n 运算符给出一个序列的 n 次浅拷贝。下边的例子可以帮助你理解这点:

Toggle line numbersToggle line numbers 1a = [3,4,5] # 一个列表

2b = [a] # 包含a的列表

3c = 4*b # b的四次拷贝

4

5# 修改 a

6a[0] == -7

7

8# 打印出 c

9print c

程序将会输出:

[[-7, 4, 5], [-7, 4, 5], [-7, 4, 5], [-7, 4, 5]]

这种情况下,列表b中放置了到列表a的引用,当b被重复的时候,仅创建了4个额外的引用。所以,当a被修改的时候,这个变化也影响到所有a的引用。这种情况通常是大多程序员不愿意看到的。你可以通过复制a中的所有元素来解决这种问题。如:a = [3, 4, 5 ]

c = [a[:] for j in range((4)] # [:]代表a的副本而不是到a的引用

注:a[:]这种方式也仅仅是创建列表a所有元素的浅拷贝,如果a中有元素为可变元素,仍然可能会有潜在问题。 --WeiZhong

标准库中的copy模块也可以用于一个对象的浅复制,另外它还支持深复制。

索引操作符 s[n] 返回序列中的第 n个对象(s[0]是第一个),如果 n 是负数,在求值之前,就先执行 n+=len(s)。如果尝试读取一个不存在的元素则会引发IndexError异常。

切片操作符s[i:j]返回一个子序列。i 和 j 必须是整数或长整数。如果被省略,那么它们的默认值分别为序列的开始或结束。切片操作同样允许负数索引。你只要记住这个公式:s[n]=s[n-len(s)] (n为正数) 或者 s[n]=s[len(s)+n] (n为负数)就行了。

Toggle line numbersToggle line numbers 1s=[1,2,3,4] # S 上界为 0 下界为 4

2print s[-100:100] #返回 [1,2,3,4] -100超出了上界,100超出了下界:等价于 s[0:4]

3print s[-100:-200] #返回 [] -100,-200均超出了上界,自动取上界:等价于s[0:0]

4print s[100:200] #返回 [] 100,200均超出了下界,自动取下界值:等价于s[4:4]

x in s 运算符检验对象 x 是否是 s 的子对象,并返回True或False。 not in 运算符刚好与 in 相反。for x in s 操作顺序迭代序列中的全部元素,这将在第五章--控制流中详细介绍。len(s)返回一个序列中的元素个数。 min(s)和max(s)返回一个序列的最小值和最大值,这两个函数只有序列中的元素可排序时返回值才有意义。(如果对一个文件对象的列表取最大值或最小值,就毫无意义)

字符串和元组是不可变对象,不能在创建之后对原始对象修改。列表则可以进行以下操作:操作 描述

s[i ] = x 为s[i]重新赋值

s[i :j ] = r 将列表片段重新赋值

del s[i ] 删除列表中一个元素

del s[i :j ] 删除列表中一个片段

s[i] = x操作将列表索引为 i 的元素重新赋值为对象 x ,并增加 x 的引用记数。如果i是负数,在求值之前,就先执行 i+=len(s),计算结果必须是一个小于len(s)的非负整数。尝试给一个不存在的索引赋值会引发 IndexError 异常. 切片分配操作符 s[i:j] = r 将列表片段s[i:j]替换为序列 r。如:

Toggle line numbersToggle line numbers 1a = [1,2,3,4,5]

2a[1] = 6 # a = [1,6,3,4,5]

3a[2:4] = [10,11] # a = [1,6,10,11,5]

4a[3:4] = [-1,-2,-3] # a = [1,6,10,-1,-2,-3,5]

5a[2:] = [0] # a = [1,6,0]

del s[i]语句从列表s中删除元素i,并将它的引用记数减1。del s[i:j]语句删除一个切片。

序列可以使用, =, == 和 != 来进行比较。当比较两个序列的时候,首先比较序列的第一个元素。如果它们不同,就马上得出结论.如果它们相同,就继续比较第二个元素,直到找到两个不同的元素或者两个序列都没有多余元素为止。字符串通过比较每个字符的内部编码决定大小(如ASCII或Unicode)。

字符串取模运算 s % d 返回一个格式化后的字符串。 需要一个格式字符串 s 作为左操作数,一个独立对象或一个元组或一个映射对象 d 作为右操作数。格式字符串 s 可以是ASCII字符串,也可以是一个Unicode字符串。这个运算符和 C 语言中的 sprintf() 函数类似。格式字符串包含两种对象类型:普通字符(不改变它的值)和转换符(% + 转换字符)--在输出结果中,转换符将格式化 d 中的相应元素,然后用格式化后的结果填充自身。如果 s 内只有一个转换符,则允许一个 d 是一个独立的非tuple对象。否则 d 就必须是一个tuple或映射对象。如果 d 是一个tuple,则转换表示符的个数必须和d的长度相等;如果d是一个映射,每个转换表示符的 % 字符之后必须有一个小括号括起来的映射对象中的key值.表Table 4.1详细列出了转换符的使用.

表 4.1. 字符串格式转换字符 输出格式

d,i 十进制整数或长整数

u 无符号十进制整数或长整数

o 八进制整数或长整数

x 十六进制整数或长整数

X 十六进制整数或长整数(大写字母)

f 浮点数如 [-]m.dddddd

e 浮点数如 [-]m .dddddde ±xx .

E 浮点数如 [-]m .ddddddE ±xx .

g,G 指数小于-4或者更高精确度使用 %e 或 %E; 否则,使用 %f

s 字符串或其他对象,使用str()来产生字符串

r 与 repr() 返回的字符串相同

c 单个字符

% 转换符标识 %

在 % 和转换字符串之间,允许出现以下修饰符,并且只能按以下顺序:1.映射对象的 key,如果被格式化对象是一个映射对象却没有这个成分,会引发KeyError异常.

2.下面所列的一个或多个:

左对齐标志

+,数值指示必须包含

0,指示一个零填充

3.指示最小栏宽的数字.转换值会被打印在指定了最小宽度的栏中并且填充在(或者右边).

4. 一个小数点用来分割浮点数

5. A number specifying the maximum number of characters to be printed from a string, the number of digits following the decimal point in a floating-point number, or the minimum number of digits for an integer.

另外,形标(*)字符用于在任意宽度的栏中代替数字. If present, the width will be read from the next item in the tuple.下边的代码给出了几个例子:

Toggle line numbersToggle line numbers 1a = 42

2b = 13.142783

3c = "hello"

4d = {'x':13, 'y':1.54321, 'z':'world'}

5e = 5628398123741234L

6

7print 'a is %d' % a # "a is 42"

8print '%10d %f' % (a,b) # " 42 13.142783"

9print '%+010d %E' % (a,b) # "+000000042 1.314278E+01"

10print '%(x)-10d %(y)0.3g' % d # "13 1.54"

11print '%0.4s %s' % (c, d['z']) # "hell world"

12print '%*.*f' % (5,3,b) # "13.143"

13print 'e = %d' % e # "e = 5628398123741234"

1.3. 字典的操作

字典用来在名字与对象之间建立映射。对一个字典可进行以下操作:操作 描述

x = d[k ] 通过 key 访问字典元素

d [k ] = x 通过 key 对字典元素进行赋值

del d[k ] 通过 key 删除某个字典元素

len(d ) 字典的元素个数

key 可以是任意不可变对象,如字符串,数字,和元组。另外,字典的关键字也可以是用逗号分隔的多个值。例如:

在这种情况下,关键字的值其实是一个元组,下面的代码和上面的代码作用是一样的:d[(1,2,3)] = "foo"

d[(1,0,3)] = "bar"

1.4. 增量赋值语句

Python提供以下的增量赋值操作:操作 等价表达式

x += y x = x + y

x -= y x = x - y

x *= y x = x * y

x /= y x = x / y

x **= y x = x ** y

x %= y x = x % y

x &= y x = x & y

x |= y x = x | y

x ^= y x = x ^ y

x >>= y x = x >> y

x

应用举例:

Toggle line numbersToggle line numbers 1a = 3

2a += 1 # a = 4

3b = [1,2]

4b[1] += 10 # b = [1, 12]

5c = "%s %s"

6c %= ("Douglas", "Adams") # c = "Douglas Adams"

需要指出的是,增量赋值语句并不对对象进行原地修改,因此也不会改变对象的性质。x += y语句创建了一个值为x + y的新对象,并将这个对象赋给 x。用户自定义类可通过定义特殊方法重载增量赋值操作符.(参见第三章,类型和对象)

1.5. 属性(.)操作符

点(.)操作符用来访问一个对象的属性,例如:

Toggle line numbersToggle line numbers 1foo.x = 3

2print foo.y

3a = foo.bar(3,4,5)

4del foo.x

点操作符并不仅仅可以用于单个表达式,例如foo.y.a.b . 它还可以用于函数的中间结果,例如a = foo.bar(3,4,5).spam .属性可以使用del语句来删除,例如del foo.x .

1.6. 类型转换

经常对内建类型进行类型转换的需要。下列内建函数提供了显式的的类型转换操作:函数 描述

int(x [,base ]) 将x转换为一个整数

long(x [,base ]) 将x转换为一个长整数

float(x ) 将x转换到一个浮点数

complex(real [,imag ]) 创建一个复数

str(x ) 将对象 x 转换为字符串

repr(x ) 将对象 x 转换为表达式字符串

eval(str ) 用来计算在字符串中的有效Python表达式,并返回一个对象

tuple(s ) 将序列 s 转换为一个元组

list(s ) 将序列 s 转换为一个列表

chr(x ) 将一个整数转换为一个字符

unichr(x ) 将一个整数转换为Unicode字符

ord(x ) 将一个字符转换为它的整数值

hex(x ) 将一个整数转换为一个十六进制字符串

oct(x ) 将一个整数转换为一个八进制字符串

repr(x)函数也可写为 x .注意str()函数和repr()函数返回的结果经常是不同的. repr()函数取得对象的表达式字符串表示,通常可以使用eval()函数来重新得到这个对象.而str()产生一个对象的简洁格式表示(用于print语句). ord()函数返回字符在ascii或Unicode字符编码中的整数顺序值. chr()和unichr()函数将一个整数分别转换为ascii或Unicode字符.

将一个字符串转换为数字或其他对象,使用int(), long(),和 float()函数. eval()函数也可以将一个包含有效表达式的字符转换为一个对象,例如:

Toggle line numbersToggle line numbers 1a = int("34") # a = 34

2b = long("0xfe76214", 16) # b = 266822164L (0xfe76214L)

3b = float("3.1415926") # b = 3.1415926

4c = eval("3, 5, 6") # c = (3,5,6)

1.7. Unicode字符串

在同一个程序中使用标准字符串和Unicode字符串会有一点点复杂.这是因为对字符串有太多种操作,包括字符串连结,比较,字典关键字查询,以及在函数中用做参数.

内建函数unicode(s [, encoding [,errors ]])可以把一个标准字符串转换为一个Unicode字符串.字符串方法u.encode([encoding [, errors ]])可以把一个Unicode字符串转换为一个标准字符串.这些转换操作需要特殊编码规则来指定16位Unicode字符串与标准8位字符来相互映射.编码参数是一个由如下值组成的特定字符串:值 描述

'ascii' 7-bit ASCII

'latin-1' or 'iso-8859-1' ISO 8859-1 Latin-1

'utf-8' 8-位可变长度编码

'utf-16' 16-位可变长度编码(可能是 little endian或 big endian)

'utf-16-le' UTF-16, little-endian 编码

'utf-16-be' UTF-16, big-endian 编码

'unicode-escape' 与Unicode文字 u"string" 相同

'raw-unicode-escape' 与原始 Unicode文字 ur"string"相同

默认编码在site模块中设置,可以通过sys.getdefaultencoding()来读取.在多数情况下,默认编码是'ascii',即就是ASCII字符,它的值在区间[0x00,0x7f]内,直接映射到Unicode字符的[U+0000, U+007F].其他关于编码的内容在第九章--输入与输出.

当转换字符串时,如果有一个字符不能被转换,那么就会引起一个UnicodeError异常.比如,如果编码规则为'ascii', Unicode字符U+1F28 就不能被转换,因为它的值太大. 同样地,字符串 "\xfc" 也不能被转换到Unicode,因为它也超出了ASCII字符范围. errors参数决定如何处理编码错误.它是一个包含下列值的字符串:值 描述

'strict' 编码错误时引起一个UnicodeError异常

'ignore' 忽略不可转换字符

'replace' 将不可转换字符用U+FFFD替代(Unicode中的U+FFFD 是标准字符串中的'?')

默认错误处理是 'strict'.

当标准字符串和Unicode字符串在表达式中混用时,标准字符串将被自动转换为Unicode字符串.例如:

Toggle line numbersToggle line numbers 1s = "hello"

2t = u"world"

3w = s + t # w = unicode(s) + t

当一个字符串方法(第三章中讲到)中使用到Unicode字符串时,结果也将总是Unicode字符串,例如:

Toggle line numbersToggle line numbers 1a = "Hello World"

2b = a.replace("World", u"Bob") # b = u"Hello Bob"

此外,即使使用replace()方法进行零替换(替换结果仍是原始字符串)时,结果仍然会是Unicode字符串.

如果一个Unicode字符串使用 % 操作符做格式字符串,所有参数在一开始都将强制转换为Unicode字符串,然后再根据格式规则连结在一起.如果一个Unicode对象被用做 % 操作符的一个参数,整个结果也将是Unicode字符串(Unicode对象被扩充),例如:

Toggle line numbersToggle line numbers 1c = "%s %s" % ("Hello", u"World") # c = "Hello " + u"World"

2d = u"%s %s" % ("Hello", "World") # d = u"Hello " + u"World"

当使用Unicode字符串时, str()和repr()函数会自动使用默认编码将Unicode字符串转换为标准字符串.对于一个Unicode字符串u, str(u)相当于u.encode(), repr(u)相当于u"%s" % repr(u.encode('unicode-escape')).

另外,许多库和内建函数只能用于操作标准字符串, Unicode字符串将会被自动使用默认编码转换为标准字符串.如果转换不可执行,会引发UnicodeError异常.

标准字符串和Unicode字符串可以比较.在这种情况下,标准字符串首先会使用默认编码强制转换为Unicode字符串.这个规则在列表和字典元素的比较操作中也同样适用.例如 'x' in [u'x', u'y', u'z'] 强制将'x'转换为Unicode,并返回True. 对于从属测试, 'W' in u'Hello World' 也同理('W'被转换为Unicode).

当使用 hash() 函数计算哈希值时,标准字符串和Unicode字符串返回同一个值(当Unicode字符串只包含[U+0000, U+007F]中的字符时).这样就可以使标准字符串和Unicode字符串在用做字典关键字时可以互换(但条件还是Unicode字符串只包含[U+0000, U+007F]中的字符),例如:

Toggle line numbersToggle line numbers 1a = { }

2a[u"foo"] = 1234

3print a["foo"] # Prints 1234

但是,应该注意在默认编码被改变为非acsii或者Unicode字符串包含非ASCII字符时,字典关键字不具有这种可以互换的行为.比如,如果'utf-8'被用做默认编码,字符串比较会返回相等,但哈希值不同:#python

a = u"M\u00fcller" # Unicode字符串

b = "M\303\274ller" # utf-8 编码格式的 a

print a == b # Prints True

print hash(a)==hash(b) # Prints False

注意,上面的例子在python2.4中会引发异常.所以上面这些言论可能已经过时. --WeiZhong

1.8. 布尔表达式

and, or,和 not关键字可以组成布尔表达式.这些操作符的特性如下:操作符 描述

x or y 如果 x 为假,返回 y ; 否则,返回 x

x and y 如果 x 为假,返回 x ; 否则,返回 y

not x 如果 x 为假,返回 True ; 否则,返回 False

当你使用一个表达式用来判断True 或 False时,任何非零的数字或非空列表,元组,字典,都返回True。零,None,以及空列表,元组,字典返回False. 布尔表达式从左至右进行计算,而且具有短路行为,也就是说只有需要时才会进行右边表达式的计算.例如表达式 a and b 只有当a为True时才计算b.注: 0 and 10/0 这样的表达式不会引发 除0错误,因为 10/0 这个表达式被短路了。 --WeiZhong

1.9. 对象的比较与身份

相等运算符 x== y 检验x和y的值是否相等.在比较列表或元组,只有当所有的元素都相等时这两个对象才是相等的.对于字典,只有当x和y有相同的关键字和相同的对应值时,才会返回相等.

身份运算符 x is y 和 x is not y 检验两个对象在内存中否指向同一个对象.通常情况下, x==y,但 x is not y.

比较操作也可以在两个不兼容的对象类型之间进行,比如一个文件和一个浮点数,不过返回的结果是任意的,这样的比较也没有任何意义.另外,比较两个不兼容的对象有可能会引发异常.

1.10. 运算优先级

Table 4.2列出了Python运算符的运算顺序(优先级).除乘方(**)外的所有运算符都是从左至右进行运算.表中靠前的运算符优先级要比后边的高些,也就是说,靠前的运算符在一个表达式中会先运算.(注:同一栏的运算符,如 x * y , x / y , x % y 有相同的优先级)

Table 4.2. 运算优先级 (由高到低)运算 名称

--------------------------------------------------------------------

(...), [...], {...} 创建元组,列表,字典

--------------------------------------------------------------------

`...` 字符串转换

--------------------------------------------------------------------

s[i ], s[i:j ], .attr 索引,切片,属性

--------------------------------------------------------------------

f(...) 函数调用s

--------------------------------------------------------------------

+x , -x , ~x 一元运算符

--------------------------------------------------------------------

x ** y 乘方(从右至左运算)

--------------------------------------------------------------------

x * y , x / y , x % y 乘,除,取模

--------------------------------------------------------------------

x + y , x - y 加,减

--------------------------------------------------------------------

x > y 移位

--------------------------------------------------------------------

x & y 按位与

--------------------------------------------------------------------

x ^ y 按位异或

--------------------------------------------------------------------

x | y 按位或

--------------------------------------------------------------------

x x > y , x >= y ,

x == y , x != y 比较,身份,序列成员检测

x y

x is y , x is not y

x in s , x not in s

--------------------------------------------------------------------

not x 逻辑非

--------------------------------------------------------------------

x and y 逻辑与

--------------------------------------------------------------------

x or y 逻辑或

--------------------------------------------------------------------

lambda args : expr lambda函数表达式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值