Differences between revisions 1 and 2
Revision 1 as of 2006-01-22 05:24:28
Size: 3883
Editor: WeiZhong
Comment:
Revision 2 as of 2006-02-07 11:18:50
Size: 11385
Editor: WeiZhong
Comment:
Deletions are marked like this. Additions are marked like this.
Line 76: Line 76:
== 序列运算 ==
'''序列支持以下操作:'''
{{{
操作 描述
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 次浅拷贝。下边的例子可以帮助你理解这点:
{{{#!python
a = [3,4,5] # 一个列表
b = [a] # 包含a的列表
c = 4*b # b的四次拷贝
 
# 修改 a
a[0] == -7
 
# 打印出 c
print 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为负数)就行了。
{{{#!python
s=[1,2,3,4] # S 上界为 0 下界为 4
print s[-100:100] #返回 [1,2,3,4] -100超出了上界,100超出了下界:等价于 s[0:4]
print s[-100:-200] #返回 [] -100,-200均超出了上界,自动取上界:等价于s[0:0]
print 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。如:
{{{#!python
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]语句从列表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.下边的代码给出了几个例子:
}}}{{{#!python
a = 42
b = 13.142783
c = "hello"
d = {'x':13, 'y':1.54321, 'z':'world'}
e = 5628398123741234L
 
print 'a is %d' % a # "a is 42"
print '%10d %f' % (a,b) # " 42 13.142783"
print '%+010d %E' % (a,b) # "+000000042 1.314278E+01"
print '%(x)-10d %(y)0.3g' % d # "13 1.54"
print '%0.4s %s' % (c, d['z']) # "hell world"
print '%*.*f' % (5,3,b) # "13.143"
print 'e = %d' % e # "e = 5628398123741234"
}}}

[:PythonEssentialRef4:第四章 运算符与表达式]

第四章 运算符与表达式

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

数值操作

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

运算                    描述
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 << y                  左移
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 < y                   小于
x > y                   大于
x == y                  等于
x != y                  不等于(与<>相同)
x >= y                  大于等于
x <= y                  小于等于

Python的比较运算可以连结在一起,如w < x < y < z 。这个表达式等价于 w < x and x < y and y < z 。

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

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

数值操作要求操作数必须是同一类型,若Python发现操作数类型不一致,就会自动进行类型的强制转换,转换规则如下:

1.如果操作数中有一个是复数,另一个也将被转换为复数
2.如果操作数中有一个是浮点数,另一个将被转换为浮点数
3.如果操作数中有一个是长整数数,另一个将被转换为长整数数
4.如果以上都不符合,则这两个数字必然都是整数,不需进行强制转换。

序列运算

序列支持以下操作:

操作                      描述
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 次浅拷贝。下边的例子可以帮助你理解这点:

   1 a = [3,4,5]        # 一个列表
   2 b = [a]            # 包含a的列表
   3 c = 4*b            # b的四次拷贝
   4  
   5 # 修改 a
   6 a[0] == -7
   7  
   8 # 打印出 c
   9 print 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为负数)就行了。

   1 s=[1,2,3,4]             # S 上界为 0 下界为 4 
   2 print s[-100:100]       #返回 [1,2,3,4] -100超出了上界,100超出了下界:等价于 s[0:4]
   3 print s[-100:-200]      #返回 [] -100,-200均超出了上界,自动取上界:等价于s[0:0]
   4 print 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。如:

   1 a = [1,2,3,4,5]
   2 a[1] = 6            # a = [1,6,3,4,5]
   3 a[2:4] = [10,11]    # a = [1,6,10,11,5]
   4 a[3:4] = [-1,-2,-3] # a = [1,6,10,-1,-2,-3,5]
   5 a[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.下边的代码给出了几个例子:

   1 a = 42
   2 b = 13.142783
   3 c = "hello"
   4 d = {'x':13, 'y':1.54321, 'z':'world'}
   5 e = 5628398123741234L
   6  
   7 print 'a is %d' % a             #  "a is 42"
   8 print '%10d %f' % (a,b)         #  " 42 13.142783"
   9 print '%+010d %E' % (a,b)       #  "+000000042 1.314278E+01"
  10 print '%(x)-10d %(y)0.3g' % d   #  "13         1.54"
  11 print '%0.4s %s' % (c, d['z'])  #  "hell world"
  12 print '%*.*f' % (5,3,b)         #  "13.143"
  13 print 'e = %d' % e              #  "e = 5628398123741234"

PythonEssentialRef4 (last edited 2009-12-25 07:10:05 by localhost)