[Python] 运算符与表达式
所有数字类型可进行以下操作:
截断除法运算符"//",也称为地板除法,把结果截取为一个整数,并且整数和浮点数均可应用。取模运算符返回的是x // y的余数,对于浮点数,取模运算符返回的是x // y的浮点余数。对于复数,取模和截断除法运算符是无效的。
以下移位和按位逻辑运算符只能应用于整数:
以下内置函数支持所有数字类型:
abs()函数返回数字的绝对值。divmod()函数返回除法操作的商和余数,只对非复数有效。pow()函数可以用于代替**运算符。round()函数将一个浮点数x四舍五入为最近的10^-n的倍数,如果省略n,它将被设为0.
以下比较运算符具有标准的数学解释,返回值为布尔型的True或False:
比较运算符可以连在一起,比如x < y < z。这类表达式等价于x < y and y < z。不允许对复数进行比较,否则会引发TypeError异常。只有当操作数属于同一类型时,对这些操作数进行运算才是有效的。对于内置数字,Python将进行强制类型转换,转换规则如下:
1) 如果操作数之一为复数,则将另一个操作数也转换为复数。
2) 如果操作数之一为浮点数,则将另一个操作数也转换为浮点数。
3) 否则,两个操作数必须同时为整数,不需要进行转换。
序列类型(包括字符串、列表和元组)支持的运算符如下所示:
"+"运算符用于连接相同类型的两个序列。s * n运算符制作一个序列的n个副本。但是,这些副本仅仅是浅复制。
所有序列都可以被解包为一列变量名称,例如:
items = [3, 4, 5]x, y, z = itemsdatetime = ((5, 19, 2008), (10, 30, "am"))(month, day, year), (hour, minute, am_pm) = datetime
将值解包到变量中时,变量的个数必须严格匹配序列中元素的个数。另外,变量的结构也必须匹配序列的结构。
索引运算符s[n]返回序列中的第n个对象,而s[0]是第一个对象。使用负数索引可以获取序列尾部的字符。试图访问超出边界的元素将引发IndexError异常。
切片运算符s[i:j]从s中提取一个子序列,它所包含的元素索引k的范围是i <= k < j。切片运算符支持使用负数索引,并且假定它关联到序列的结尾。
x in s运算符测试对象x是否在序列s中,返回值为True或False。类似地,x not in s 运算符测试x是否不在序列s中。对于字符串对象,in和not in运算符接受子字符串。比如:" 'hello' in 'hello world' "。需要注意的是,in运算符不支持通配符或任意类别的模式匹配。
for x in s运算符用于迭代序列的所有元素。len(s)返回序列中元素的个数。min(s)和max(s)分别返回一个序列中的最小值和最大值。sum(s)用于对s中的所有项求和,但只在其中的各项代表数字时有效。
字符串和元组是不可变的,创建后不能修改。列表可通过以下运算符进行修改:
s[i] = x运算符将列表的元素i修改为引用对象x,同时增加x的引用计数。负索引值将关联到列表结尾,试图给超出范围的索引赋值将引发IndexError异常。切片赋值运算符s[i:j] = r将使用序列r中的元素替换元素k,其中k的范围是i <= k < j。如果有必要,将对序列s进行扩展或收缩,以便容纳r中的所有元素,例如:
a = [1, 2, 3, 4, 5]a[1] = 6 # a = [1, 6, 3, 4, 5]a[2:4] = [10, 11] # a = [1, 6, 10, 11, 5]a[3:4] = [-1, -2, -3] # a = [1, 6, 10, -1, -2, -3, 5]a[2:] = [0] # a = [1, 6, 0]
切片赋值可以提供一个可选的步进参数。但这种行为受到的限制更大,右边的参数必须与要替换切片的元素个数完全相同。
del s[i]运算符从列表中删除元素i,同时减少它的引用计数。del s[i:j]删除切片内的所有元素。切片删除也可以指定步进参数。
使用运算符<、>、<=、>=、==、!=可以对序列进行比较。比较两个序列时,首先比较每个序列的第一个元素。如果它们不同,即可以得出结论。如果它们相同,就继续比较。如果a是b的子序列,那么a < b。
取模运算符(s % d)生成格式化的字符串,其中s是一个格式字符串,而d是一个对象元组或映射对象(字典)。格式字符串包含两类对象:普通字符和转换说明符,将使用可表示相关元组或映射中元素的格式化字符串来替换这些转换说明符。如果d是一个元组,转换说明符的个数必须与d中对象的个数保持一致。如果d是一个映射,每个转换说明符都必须与映射中的一个有效键名关联。每个转换说明符都以%开始,如下表:
在%字符和转换字符之间,可以出现以下修饰符,并且只能按照以下顺序出现:
1) 位于括号中的一个键名,用于从映射对象中选出一个具体项。
2) -,左对齐标志。默认是右对齐。
3) +,表示应该包含数字符号。
4) 0,表示一个零填充。
5) 一个指定最小自动宽度的数字。
6) 一个小数点,用于按照精度分割字段宽度。
7) 一个数字,指定要打印字符串中的最大字符个数,浮点数中小数点之后的位数,或者整数的最小位数。
星号"*"字符用于在任意宽度的字段中替换数字。
以下代码给出一些例子:
a = 42b = 13.142783c = "hello"d = {'x':13, 'y':1.54321, 'z': 'world'}e = 5628398123741234r = "a is %d" % a # r = "a is 42"r = "%10d %f" % (a, b) # r = " 42 13.142783"r = "%+010d %E" % (a, b) # r = "+0000000042 1.314278E+01"r = "%(x)-10d %(y)0.3g" % d # r = "13 1.54"r = "%0.4s %s" % (c, d['z']) # r = "hell world"r = "%*.*f" % (5, 3, b) # r = "13.143"r = "e = %d" % e # r = "e = 5628398123741234"
字符串格式化有一种更加高级的形式,即使用字符串的s.format(args, kwargs)方法。该方法收集位置参数和关键字参数的任意集合,并使用它们的值来替换s中嵌入的占位符。例如:
r = "{0} {1} {2}".format{'GOOG', 100, 490.91}r = "{name} {shares} {price}".format{name='GOOG', shares=100, price=490.10}
如果要输出一个"{"或"}",必须使用"{{"或"}}"的形式。使用占位符还可以执行其他索引和属性查找,例如:
stock = { 'name': 'GOOG', 'shares': 100, 'price': 490.91}r = "{0[name]} {0[shares]} {0[price]}".format(stock)
这些扩展中只允许使用名称,而不支持任意的表达式、方法调用和其他操作。另外,还可以指定格式说明符。方法是用一个冒号":"给每个占位符添加可选的格式说明符,例如:
r = "{name:8} {shares:8d} {price:8.2f}".format(name='GOOG', shares=100, price=490.10)
说明符的一般格式是[fill[align]][sign][0][width][.pricision][type],[ ]中的每个部分都是可选的。width说明符指定要使用的最小字段宽度,align说明符的值可取"<"、">"或"^"之一,分别代表在字段中左对齐、右对齐和居中对齐。fill是一个可选的填充字符,用于填充空白。type说明符表示数据的类型。格式说明符的sign部分是"+"、"-"或空格" "之一,表示符号。说明符的precision部分用于为十进制数提供精度位置。
字典提供名称和对象之间的映射,它支持的操作如下:
键的值可以是任意不可变对象,如字符串、数字和元组。另外,字典的键也可以是一列用逗号分开的值,例如:
d = {}d[1, 2, 3] = "foo"d[1, 0, 3] = "bar"# 等价于d[(1, 2, 3)] = "foo"d[(1, 0, 3)] = "bar"
set和frozenset类型支持大量常见的集合操作,如下所示:
并集、交集和差集操作的结果与最左边的操作数具有相同类型。例如,如果s是一个frozenset,而t是一个set,那么结果的类型将是frozenset。
Python提供的增量赋值运算符如下所示:
增量赋值不会违反可变性或者原地修改对象。因此,执行代码 x += y时,将创建一个值为x + y的全新对象x。
点"."运算符用于访问对象的属性,例如
foo.x = 3print(foo.y)a = foo.bar(3, 4, 5)
表达式中可以出现多个点运算符,如foo.y.a.b。点运算符还可以用于函数的中间结果,如a = foo.bar(3, 4, 5).spam。
f(args)运算符用于调用f上的函数。函数的每个参数都是一个表达式。在调用函数前,将从左到右对所有参数表达式进行求值,这有时称为应用序求值。使用functools模块中的partial()函数可以对函数参数进行部分求值,例如:
def foo(x, y, z): return x + y + zfrom functools import partialf = partial(foo, 1, 2) # 为foo的参数x和y提供值f(3) # 调用foo(1, 2, 3)
partial()函数对一个函数的某些参数求值,返回一个稍后可以调用的对象,以提供余下的参数。函数参数的部分求值与叫做科里化的过程关系十分紧密。所谓科里化的机制是:把一个带有多个参数的函数分解为一系列函数,其中每个函数带有其中一个参数。
有时必须在内置类型之间执行转换,只需用类型名称作为函数。另外,还有几个内置函数可用于执行特殊类别的转换。所有这些函数均返回一个新对象,该对象代表了转换后的值。
需要注意的是,str()和reprt()函数返回的结果可能不同。repr()函数通常会创建一个表达式字符串,可以使用eval()对它求值以重新创建对象。ord()函数返回一个字符的整数顺序值。在Unicode中,这个值就是一个整数代码点。chr()函数用于将整数转换成字符。在创建容器的函数中,如list()、tuple()、set()等,参数可以是支持迭代的任意对象,而迭代生成的所有项将用于填充要创建的对象。
and、or和not关键字构成了布尔表达式。这些运算符的行为如下所示:
使用表达式来判断True或False值时,True、任意非零数字、非空字符串、列表、元组或字典都将返回True,而False、零、None和空的列表、元组和字典都将返回False。布尔表达式从左至右求值,而且只有需要时才会计算右边的操作数。
等于运算符(x == y)可以测试x和y的值是否相等。对于列表和元组,只有其中的所有元素都相等,它们才相等。而对于字典,只有当x和y的键都相同,而且键相同的所有对象的值都相等才会返回True。两个集合相等的条件是用==运算符进行比较时,它们具有相同的元素。
身份运算符(x is y和x is not y)可以测试两个对象是否引用了内存中的同一个对象。一般而言,x == y,但x is not y。
比较操作也可以在两个非兼容对象之间进行,如一个文件和一个浮点数,但返回结果是任意的,可能没有意义。另外也可能导致异常。
Python运算符的操作顺序如下表:
运算顺序并非由上表的x和y的类型决定。因此,即便是用户自定义对象,也可以重新定义每个运算符。
常见的编程模式是根据表达式的结果,有条件地进行赋值,例如:
if a <= b: minvalue = aelse: minvalue = b
使用条件表达式可以简化这段代码,例如:
minvalue = a if a <= b else b
在这类表达式中,首先求值的是中间的条件。如果结果为True,再对if语句左面的表达式求值,否则就会对else后面的表达式求值。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。