简明python教程 --C++程序员的视角(一):数值类型、字符串、运算符和控制流
最初的步骤
- Python是大小写敏感的
- 任何在#符号右面的内容都是注释
- >>> help('print')
在“print
”上使用引号,那样Python就可以理解我是希望获取关于“print”的帮助而不是想要打印东西。
数据类型
在Python中有4种类型的数——整数、长整数、浮点数和复数(Python 有五个内置的简单类型:bool
、int
、long
、float
和 complex
)。
2、0177,0x7F
是整数的例子。Python 在这一点上更像 C,因为它的类型范围是依赖于平台的。int 是一种 32 位的整数值。因而,它被限制为只能保存从 -232 到 232 - 1 之间的值(在多数平台上)- 长整数类型的精度不受限,仅计算机内存对它有影响,如 100L。当需要额外的精度时,Python自动将整型变换升级为长整型,而不用担心溢出。
>>> 2 ** 10
1024
>>> 2 ** 50
1125899906842624L
3.23
和52.3E-4
是浮点数的例子。E标记表示10的幂。在这里,52.3E-4
表示52.3 * 10
-4。浮点值始终是按双精度处理的。(-5+4j)
和(2.3-4.6j)
是复数的例子。在 Python 中,复数的虚部被表示为 j。通过使用real
和imag
属性,即可访问复数的不同部分。
在Python中一切皆是对象,如果您不怕麻烦,还可以直接使用它们的构造函数。
>>> b = bool(True) >>> i = int(100) >>> l = long(100) >>> f = float(100.1) >>> c = complex(3.0, 1.2) >>> print b, i, l, f, c True 100 100 100.1 (3+1.2j) >>> print c.real, c.imag 3.0 1.2
字符串
在双引号中的字符串与单引号中的字符串的使用完全相同。
使用 'What\'s your name?',或者"What's your name?"
利用三引号,你可以指示一个多行的字符串。你可以在三引号中自由的使用单引号和双引号。
在一个字符串中,行末的单独一个反斜杠表示字符串在下一行继续,而不是开始一个新的行。
"This is the first sentence. This is the second sentence."
等价于:
自然(原始 raw)字符串:指示某些不需要如转义符那样的特别处理的字符串,自然字符串通过给字符串加上前缀r
或R
来指定。
r"Newlines are indicated by \n"
一定要用自然字符串处理正则表达式。否则会需要使用很多的反斜杠。例如,后向引用符可以写成'\\1'
或r'\1'
。
Unicode字符串:Python允许你处理Unicode文本——你只需要在字符串前加上前缀u
或U。
u"This is a Unicode string."
记住,在你处理文本文件的时候使用Unicode字符串,特别是当你知道这个文件含有用非英语的语言写的文本。
字符串是不可变的:这意味着一旦你创造了一个字符串,你就不能再改变它了。
按字面意义级连字符串:如果你把两个字符串按字面意义相邻放着,他们会被Python自动级连。例如,'What\'s' 'your name?'
会被自动转为"What's your name?"
字符串方法:字符串是str类型的对象,这些对象方法可以完成包括检验一部分字符串和去除空格在内的各种工作。如果要了解这些方法的完整列表,请参见help(str)
。
startswith
方法是用来测试字符串是否以给定字符串开始。in
操作符用来检验一个给定字符串是否为另一个字符串的一部分。find
方法用来找出给定字符串在另一个字符串中的位置,或者返回-1以表示找不到子字符串。str
类也有以一个作为分隔符的字符串的join
序列的项目的整洁的方法,它返回一个生成的大字符串。
基本概念
在 Python 中,不需要使用特殊字符(或符号)来指示语句的结束。这与有些语言不同。例如,基于 C 的语言使用分号(;
)来指示代码行的结束。Python假定每个物理行对应一个逻辑行。默认地,Python希望每行都只使用一个语句,这样使得代码更加易读。
一个物理行中使用多于一个逻辑行,那么你需要使用分号(;)来特别地标明这种用法。
如果某个程序行太长,可以在文件中的下一物理行继续这一行。没有硬性规定一个代码行应该多长。但是一般限制为 80 个字符,这容易适合大多数显示器的一个打印页面。有几种方式来扩展超过一行的代码语句:
- 三引号字符串可以扩展到多个行。
- 括号中的表达式可以扩展到多个行。逻辑行中使用了圆括号、方括号或波形括号的时候,不需要使用反斜杠。这被称为暗示的行连接。
- 可以使用继续字符(
\
)来在多行分割语句。它被称为明确的行连接。
在逻辑行首的空白(空格和制表符)用来决定逻辑行的缩进层次,从而用来决定语句的分组,这意味着同一层次的语句必须有相同的缩进。(可以在编辑器中设定用4个空格替换Tab)
与其他编程语言使用特殊的字符来区分代码块(比如基于 C 的语言中的花括号{
和 }
)不同,在python的流控制语句中,流控制指令后跟一个冒号(:
),然后再是一个程序语句块,Python 需要缩进以指示代码块。
【注释】
1 无论是行注释还是段注释,均以#加一个空格来注释。
2 如果需要在代码中使用中文注释,必须在python文件的最前面加上如下注释说明:
# -* - coding: UTF-8 -* -
3 如下注释(#!)用于(Unix可执行脚本)指定解释器
#! /usr/bin/env python
Unix可执行脚本:
- 第一行是特定的:特殊形式的注释,它被称作组织行 ——源文件的头两个字符是#!,后面跟着一个程序。这行告诉你的Linux/Unix系统当你执行你的程序的时候,它应该运行哪个解释器。
- 往往拥有可执行权限:在Unix系统上使用chmod +x myfile这条shell命令赋予这个文件(文件可以没有.py后缀)执行的权限,你就能够在操作系统的shell中敲入> myfile运行它,就好像这是个二进制文件一样。
- 如果在shell中敲入> python myfile来运行程序,是不需要#!特殊注释的。
建议使用这种形式——#!/usr/bin/env python,而不是——#!/usr/bin/python,让env程序自动搜索PATH环境变量中罗列的所有目录,可以避免硬编码Python解释器的路径。
运算符和表达式
运算符 | 名称 | 说明 | 例子 |
---|---|---|---|
+ | 加 | 两个对象相加 |
3 + 5得到8。'a' + 'b'得到'ab'。 'a'+6是错误的。 python不支持自增运算符和自减运算符。例如i++/i--是错误的,但i+=1是可以的 |
- | 减 | 得到负数或是一个数减去另一个数 | -5.2得到一个负数。50 - 24得到26。 |
* | 乘 | 两个数相乘或是返回一个被重复若干次的字符串 | 2 * 3得到6。'la' * 3得到'lalala'。 |
** | 幂 |
返回x的y次幂 |
3 ** 4得到81(即3 * 3 * 3 * 3) |
/ | 除 | x除以y |
1/2在python2.5之前会等于0.5,在python2.5之后会等于0(整数的除法得到整数结果)。4.0/3或4/3.0得到1.3333333333333333 |
// | 取整除 | 返回商的整数部分 | 4 // 3.0得到1.0 |
% | 取模 | 返回除法的余数 | 8%3得到2。-25.5%2.25得到1.5 |
<< | 左移 | 把一个数的比特向左移一定数目(每个数在内存中都表示为比特或二进制数字,即0和1) | 2 << 2得到8。——2按比特表示为10 |
>> | 右移 | 把一个数的比特向右移一定数目 | 11 >> 1得到5。——11按比特表示为1011,向右移动1比特后得到101,即十进制的5。 |
& | 按位与 | 数的按位与 | 5 & 3得到1。 |
| | 按位或 | 数的按位或 | 5 | 3得到7。 |
^ | 按位异或 | 数的按位异或 | 5 ^ 3得到6 |
~ | 按位翻转 | x的按位翻转是-(x+1) | ~5得到6。 |
< | 小于 | 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 | 5 < 3返回0(即False)而3 < 5返回1(即True)。比较可以被任意连接:3 < 5 < 7返回True。 |
> | 大于 | 返回x是否大于y | 5 > 3返回True。如果两个操作数都是数字,它们首先被转换为一个共同的类型。否则,它总是返回False。 |
<= | 小于等于 | 返回x是否小于等于y | x = 3; y = 6; x <= y返回True。 |
>= | 大于等于 | 返回x是否大于等于y | x = 4; y = 3; x >= y返回True。 |
== | 等于 | 比较对象是否相等 | x = 2; y = 2; x == y返回True。x = 'str'; y = 'stR'; x == y返回False。x = 'str'; y = 'str'; x == y返回True。 |
!= | 不等于 | 比较两个对象是否不相等 | x = 2; y = 3; x != y返回True。 |
not | 布尔“非” | 如果x为True,返回False。如果x为False,它返回True。 | x = True; not x返回False。(相当于C++里的!) |
and | 布尔“与” | 如果x为False,x and y返回False,否则它返回y的计算值。 | x = False; y = True; x and y,由于x是False,返回False。在这里,Python不会计算y,因为它知道这个表达式的值肯定是False(因为x是False)。这个现象称为短路计算。(相当于C++里的&&) |
or | 布尔“或” | 如果x是True,它返回True,否则它返回y的计算值。 | x = True; y = False; x or y返回True。短路计算在这里也适用。(相当于C++里的||) |
运算符优先级
运算符 | 描述 |
---|---|
lambda | Lambda表达式 |
or | 布尔“或” |
and | 布尔“与” |
not x | 布尔“非” |
in,not in | 成员测试 |
is,is not | 同一性测试 |
<,<=,>,>=,!=,== | 比较 |
| | 按位或 |
^ | 按位异或 |
& | 按位与 |
<<,>> | 移位 |
+,- | 加法与减法 |
*,/,% | 乘法、除法与取余 |
+x,-x | 正负号 |
~x | 按位翻转 |
** | 指数 |
x.attribute | 属性参考 |
x[index] | 下标 |
x[index:index] | 寻址段 |
f(arguments...) | 函数调用 |
(expression,...) | 绑定或元组显示 |
[expression,...] | 列表显示 |
{key:datum,...} | 字典显示 |
'expression,...' | 字符串转换 |
结合规律
- 运算符通常由左向右结合,即具有相同优先级的运算符按照从左向右的顺序计算。例如,
2 + 3 + 4
被计算成(2 + 3) + 4
。 - 一些如赋值运算符那样的运算符是由右向左结合的,即
a = b = c
被处理为a = (b = c)
。
表达式
注意Python如何打印“漂亮的”输出。尽管我们没有在'Area is'
和变量area
之间指定空格,Python自动在那里放了一个空格,这样我们就可以得到一个清晰漂亮的输出,而程序也变得更加易读(因为我们不需要担心输出之间的空格问题)。这是Python如何使程序员的生活变得更加轻松的一个例子。
控制流
在Python中有三种控制流语句——if
、for
和while
。还有
相关的break
和continue
语句。
if-elif-else
语句
我们为内建的raw_input
函数提供一个字符串,这个字符串被打印在屏幕上,然后等待用户的输入。一旦我们输入一些东西,然后按回车键之后,函数返回输入。
对于raw_input
函数来说是一个字符串。我们通过int
把这个字符串转换为整数,并把它存储在变量guess
中。事实上,int
是一个类,不过你想在对它所需了解的只是它把一个字符串转换为一个整数(假设这个字符串含有一个有效的整数文本信息)。
注意我们使用了缩进层次来告诉Python每个语句分别属于哪一个块,if
语句在结尾处包含一个冒号——我们通过它告诉Python下面跟着一个语句块。
带有冒号字符的 if
和 else
语句的终止,以及 if
和 else
块中语句的缩进。正如所提到的,这两个特征是 Python 中流控制语句所必需的。
while-else语句
True
和False
被称为布尔类型。在检验重要条件的时候,布尔类型十分重要,它们并不是真实的值1
。
在这里else块事实上是多余的,因为你可以把其中的语句放在同一块(与while
相同)中,跟在while
语句之后,这样可以取得相同的效果。如果你从for
或while
循环中break,任何对应的循环else
块将不执行。
for..in循环
循环语句:
for 变量 in 集合 : … else : …
python不支持类似c的for(i=0;i<5;i++)这样的循环语句,但可以借助range模拟:
for x in range(0,5,2): print x
range
返回一个序列的数,这个序列从第一个数开始到第二个数为止。例如,range(1,5)
给出序列[1, 2, 3, 4]
。默认地,range
的步长为1。如果我们为range
提供第三个数,那么它将成为步长。例如,range(1,5,2)
给出[1,3]
。记住,range 向上 延伸到第二个数,即它不包含第二个数。
else
部分是可选的。如果包含else,它总是在for
循环结束后执行一次,除非遇到break语句。
记住,for..in
循环对于任何序列都适用。这里我们使用的是一个由内建range
函数生成的数的列表,但是广义说来我们可以使用任何种类的由任何对象组成的序列!
Python 中的 for
循环很特殊,与 Python 编程语言中内置的容器数据类型紧密相关。由于 Python 容器类型的丰富特性,for
循环非常强大。本质上,for
循环涉及到一个迭代器(iterator),用于在集合中逐项移动。
下面部分涉及到容器类型 。
for
循环有一个简单的语法,使您可以从容器对象中提取单个项目并对其进行某些操作。简单地说,使用 for
循环,可以迭代中对象集合的项目。对象集合可以是任何 Python 容器类型,包括tuple
、string
和 list
类型。
但是容器 metaphor 的功能比这三种类型更强大。metaphor 包括其他序列类型,如 dictionary
和 set
,将来的文章中将对它们进行讨论。但是请稍等!还有更多信息:for
循环可以用于迭代支持迭代 metaphor 的任何对象,这使 for
循环非常有用。
tuple
类型是不可变的异构容器。这主要是说 tuple
可以存放不同类型的对象,但是它一旦创建,就无法更改。下面用for
循环迭代tuple
的元素。
>>> t = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> count = 0 >>> for num in t: ... count += num ... else: ... print count ... 45 >>> count = 0 >>> for num in t: ... if num % 2: ... continue ... count += num ... else: ... print count ... 20
string
是不可变的同构容器,这意味着它仅能存放字符且一旦建立将无法修改。下面演示如何使用 Python string
作为 for
循环的容器。
>>> st = "Python Is A Great Programming Language!" # 一次打印 string 中的一个字符 # 逗号使 print 语句打印字符值时后面跟着空格字符,而不是换行字符。如果没有后面的逗号,字符将全部打印在单独的行中,会很难读。 >>> for c in st: ... print c, ... P y t h o n I s A G r e a t P r o g r a m m i n g L a n g u a g e ! # 调用 string 对象的 lower 方法返回的临时 string,lower 方法将 string 中的所有字符转换为小写 >>> count = 0 >>> for c in st.lower(): ... if c in "aeiou": ... count += 1 ... else: ... print count ... 12
list
是异构可变容器,这意味着它可以存放不同类型的对象且创建后可以修改。使用 for
循环使处理容器中的每个项目非常简单,甚至处理包含各种不同对象的 list
也是如此。下面演示如何使用 list
和 for
循环。
>>> mylist = [1, 1.0, 1.0j, '1', (1,), [1]] >>> for item in mylist: ... print item, "\t", type(item)) ... 1 <type 'int'> 1.0 <type 'float'> 1j <type 'complex'> 1 <type 'str'> (1,) <type 'tuple'> [1] <type 'list'>
for
循环主体可以修改其正在迭代的 list
。正如您可能认为的,这样并不好,如果进行此操作,Python 解释器将无法很好地工作。
>>> mylist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> for item in mylist: ... if item % 2: ... mylist.insert(0, 100) ... ^CTraceback (most recent call last): File "<stdin>", line 3, in ? KeyboardInterrupt >>> print mylist [100, ...., 100, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Many lines deleted for clarity >>> mylist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> for item in mylist[:]: # 使用切片运算符创建原始 list 的副本,for
循环将迭代该副本,而对原始list
进行修改 ... if item % 2: ... mylist.insert(0, 100) ... >>> print mylist [100, 100, 100, 100, 100, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
本例中的第一个 for
循环只要在原始 list
中发现奇数,它就在 list
的开始插入数值 100。当然,这是一种演示此问题的不同寻常的方式,但却非常好。一旦在三个点的 Python 提示后按 Enter 键,Python 解释器就处于无限循环的混乱中。要停止这种混乱,必须通过按 Ctrl-C(其在 Python 输出中显示为 ^C
)来中断进程,然后会出现 KeyboardInterrupt
异常。如果打印出修改的 list
,将看到mylist
现在包含大量的值为 100 的元素(新元素的准确数量取决于您中断循环的速度)。
本例中的第二个 for
循环演示了如何避免此问题。使用切片运算符创建原始 list
的副本。现在 for
循环将迭代该副本,而对原始list
进行修改。最终的结果是修改后的原始 list
,它现在以五个值为 100 的新元素开始。
Python for
循环更像 foreach
循环。基于 C 的编程语言具有 for
循环,但它的设计目的是对一系列操作执行特定次数。Python for
循环可以通过使用内置的 range
和 xrange
方法来模拟该行为。
>>> r = range(10) >>> print r [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> type(r) <type 'list'> >>> xr = xrange(10) >>> print xr xrange(10) >>> type(xr) <type 'xrange'>
本例首先演示了 range
方法,它创建一个包含一系列整数的新 list
。调用 range
方法的一般形式是提供单个值,用作整数 list
的上限。零为起始值。因此,调用 range(10)
将创建包含整数 0 至 9(包含 9)的 list
。
range
方法接受起始索引以及步长。所以,调用range(11,20)
将创建从 11 至 19(包含 19)的整数 list
,而调用 range(12, 89, 2)
将创建从 12 至 88 的偶数 list
。
由于 xrange
方法也创建整数 list
(其使用相同参数),所以它与 range
方法非常相似。但是,xrange
方法仅在需要时才在 list
中创建整数。尝试打印出新创建的 xrange
时除了 xrange
的名称,不会显示任何数据。当需要迭代大量整数时,xrange
方法更适用,因为它不会创建极大的 list
,那样会消耗大量计算机内存。
下面演示了如何在 for
循环内使用 range
方法来创建整数 1 至 10(包含 10)的乘法表。
>>> for row in range(1, 11): ... for col in range(1, 11): ... print "%3d " % (row * col), ... print ... 1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
本例使用两个 for
循环,外面的 for
循环关注乘法表中的每一行,嵌套的 for
循环关注每行内的列。每个循环都迭代包含整数 1 至 10(包含 10)的 list
。
最里面的 print
语句使用了一个名为 字符串格式化 的新概念来创建格式设置精美的表。字符串格式化是一种非常有用的技术,用于以格式设置精美的布局创建由不同数据类型组成的 string
。现在详细信息并不重要,将来的文章中将讲述这些内容(了解 C 编程语言的 printf
方法的任何人都会很熟悉这些内容)。在本例中,字符串格式化指定将从整数创建新 string
且需要保留三个字符来存放该整数(如果该整数小于三个字符,将在左边用空格填补,从而使数据排列整齐)。
第二个 print
语句用于打印新行,从而使乘法表中的下一行被打印在新的行中。
range
方法还可用于迭代容器,通过使用适当的索引访问序列中的每一项。要进行此操作,需要包含容器的允许范围索引值的整数list
,这可以通过使用 range
方法和 len
方法来轻松实现。
>>> st = "Python Is A Great Programming Language!" >>> for index in range(len(st)): ... print st[index], ... P y t h o n I s A G r e a t P r o g r a m m i n g L a n g u a g e ! >>> for item in st.split(' '): ... print item, len(item) ... Python 6 Is 2 A 1 Great 5 Programming 11 Language! 9
第一个 for
循环使用 len
方法作为 range
方法的参数,创建可用于单独访问 string
中每个字符的整数 list
。
第二个 for
循环还显示了如何将 string
分割为子字符串的 list
(使用空格字符来指示子字符串的边界)。for
循环迭代子字符串 list
,打印每个子字符串及其长度。
break语句
break
语句是用来终止while或for循环语句的,即哪怕循环条件没有称为False
或序列还没有被完全递归,也停止执行循环语句。一个重要的注释是,如果你从for
或while
循环中 终止 ,任何对应的循环else
块将不执行。
输入字符串的长度通过内建的len
函数取得。
continue语句
continue
语句被用来告诉Python跳过当前while或for循环块中的剩余语句,然后 继续 进行下一轮循环。