Python 非编程员教学旨在简介 Python 编程语言,本教学为没有编程经验的人而设。
如果您有其他编程语言的经验,我建议您看 Guido van Rossum 撰写的 The Python Tutorial。
本文件有 LATE X, HTML, PDF 及 Postscript 的格式,可往 http://www.honors.montana.edu/~jjc/easytut/ 查看所有这些格式。
假如您有任何问题或建议,可联络我 jjc@iname.com,欢迎有关本教学的问题及建议,我会尽我所能解答您任何问题。
感谢 James A. Brown 撰写大部分 Windows 安装资料,亦感谢 Elizabeth Cogliati 有关原文的投诉 :) (那对于非编程员来说几乎不可用)、校对及建议,感谢 Joe Oppegaard 撰写所有练习,感谢我遗漏了的所有人。
以下是您会觉得有用的一些连结:
您从未尝过编程,在进行这教学时,我会教您如何编程。其实只有一种方法学习编程,就是要看源码及撰写源码。我现在就要您看很多源码,您要输入这儿的源码看看有甚么发生,研究一下再作一些改变。最坏的情况就是源码不能运作,当我输入源码时,它会格式化如下:
##Python is easy to learn
print "Hello, World!"
那是多么容易与其他文字分辨开来,要令它混乱,我亦会以同样字型列印电脑的输出结果。
现在要继续更重要的东西,要以 Python 编程,您需要 Python 软件。如果您仍未有 Python 软件,可往http://www.python.org/download/ 取得适合您的平台的版本,将它下载,看过指引后再安装。
Windows 安装程式会下载至档案,透过按两下已下载的图示可执行档安,安装然后会继续。
如果您取得 Unix 源程式码,如果您想使用 IDLE,请确定您以 tk 副档案编译。
Python 2.0 (#4, Dec 12 2000, 19:19:57)
[GCC 2.95.2 20000220 (Debian GNU/Linux)] on linux2
Type "copyright", "credits" or "license" for more information.
IDLE 0.6 -- press F1 for help
>>>
>>> 是 Python 的方式,告诉您在互动模式,在互动模式,您输入的东西会立即执行。尝试输入
1+1 ,Python 会回应 2。互动模式允许您测试及查看 Python 会做些甚么。如果您曾经觉得有需要研究新的
Python 句式,可往互动模式并尝试一下。
File 再按 New Window,在本视窗输入以下句子:
print "Hello, World!"
首先储存程式,往 File 再按 Save ,储存为 hello.py。(如果您想的话,可将它储存为预设以外的其他目录。)
现在它已储存,可以执行了。
接着透过 Edit 再按 Run script 执行程式,这会在 *Python Shell*
视窗输出 Hello, World!。
仍然有混乱吗?可尝试 IDLE 的教学: http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html
python
而无须任何参数。要执行程式,可以文字编辑器建立 (Emacs 有很好的 python 模式) 并以 python 程式名称执行它。
print "Hello, World!"
假如您使用指令行执行程式,然后以文字编辑器输入,储存为 hello.py 并以 ``python hello.py '' 执行。
否则可以往 IDLE,建立新视窗,并建立在 1.4 部分的程式。
当程式执行时,会列印以下一行:
Hello, World!
现在我不会每次也告诉您,但当我向您展示一个程式时,建议您将它输入及执行。当我输入一次会学得更好,您亦可能会这样。
以下是一个更复习的程式:
print "Jack and Jill went up a hill"
print "to fetch a pail of water;"
print "Jack fell down, and broke his crown,"
print "and Jill came tumbling after."
当您执行这程式时,会列印:
Jack and Jill went up a hill
to fetch a pail of water;
Jack fell down, and broke his crown,
and Jill came tumbling after.
当电脑执行这程式时,首先会看到这行:
print "Jack and Jill went up a hill"因此电脑会列印:
Jack and Jill went up a hill
接着电脑会继续下一行并看到:
print "to fetch a pail of water;"
因此电脑会在萤幕列印:
to fetch a pail of water;
电脑会继续查看每行,跟随指令,并继续下一行。电脑会继续执行指令,直至程式结束。
print "2 + 2 is", 2+2
print "3 * 4 is", 3 * 4
print 100 - 1, " = 100 - 1"
print "(33 + 2) / 5 + 11.5 = ",(33 + 2) / 5 + 11.5
而以下是程式执行的输出结果:
2 + 2 is 4
3 * 4 is 12
99 = 100 - 1
(33 + 2) / 5 + 11.5 = 18.5
您会看到 Python 可以将您千元的电脑变为 5 元的计算机。
Python 在数字上有六个基本的操作:
| 操作 | 符号 | 范例 |
| 指数 | ** |
5 ** 2 == 25 |
| 乘数 |
* |
2 * 3 == 6 |
| 除数 | / |
14 / 3 == 4 |
| 余数 | % |
14 % 3 == 2 |
| 加数 | + |
1 + 2 == 3 |
| 减数 | - |
4 - 3 == 1 |
留意除数会跟随规则,如果不以小数开始,就没有小数结束。(注意:在 Python 2.3 会有所改变) 以下的程式会显示:
print "14 / 3 = ",14 / 3输出结果如下:
print "14 % 3 = ",14 % 3
print "14.0 / 3.0 =",14.0 / 3.0
print "14.0 % 3.0 =",14 % 3.0
print "14.0 / 3 =",14.0 / 3
print "14.0 % 3 =",14.0 % 3
print "14 / 3.0 =",14 / 3.0
print "14 % 3.0 =",14 % 3.0
14 / 3 = 4留意 Python 如何视乎有没有使用小数值,而有不同的答案。
14 % 3 = 2
14.0 / 3.0 = 4.66666666667
14.0 % 3.0 = 2.0
14.0 / 3 = 4.66666666667
14.0 % 3 = 2.0
14 / 3.0 = 4.66666666667
14 % 3.0 = 2.0
操作的次序与数学一样:
() ** *, 除数 \, 及余数 % + 及减数 -
通常在编程中,您做的都是复杂的东西,而且之后可能不会记得做了些甚么。如有这样的情况发生,程式应该被评论。评论就对您及其他编程员解释正在发生的东西。例如:
#Not quite PI, but an incredible simulation留意评论以
print 22.0/7.0
# 开始,是用来与其他阅读这程式的人沟通,以及方便您将来查看。
Denmark.py
print "Something's rotten in the state of Denmark."
print " -- Shakespeare"
输出结果:
Something's rotten in the state of Denmark.
-- Shakespeare
School.py
#This is not quite true outside of USA
# and is based on my dim memories of my younger years
print "Firstish Grade"
print "1+1 =",1+1
print "2+4 =",2+4
print "5-2 =",5-2
print "Thirdish Grade"
print "243-23 =",243-23
print "12*4 =",12*4
print "12/3 =",12/3
print "13/3 =",13/3," R ",13%3
print "Junior High"
print "123.56-62.12 =",123.56-62.12
print "(4+3)*2 =",(4+3)*2
print "4+3*2 =",4+3*2
print "3**2 =",3**2
Output:
Firstish Grade
1+1 = 2
2+4 = 6
5-2 = 3
Thirdish Grade
243-23 = 220
12*4 = 48
12/3 = 4
13/3 = 4 R 1
Junior High
123.56-62.12 = 61.44
(4+3)*2 = 14
4+3*2 = 10
3**2 = 9
编写一个程式,以独立的字串列印您的全名及生日。
编写一个程式,显示全部六个数学函式的应用。
print "Halt!"
s = raw_input("Who Goes there? ")
print "You may pass,", s
当我执行程式,以下是我萤幕的显示:
Halt!
Who Goes there? Josh
You may pass, Josh
当然,当您执行程式时,萤幕会因 raw_input 句式而有不同。执行程式时可能会留意到 (您已执行了程式,是吗?) 您要如何输入您的名字并按 Enter。然后程式会列印更多文字及您的名字,这是输入的范例,程式达到某一点时,它会等候使用者输入一些程式稍后会使用的资料。
当然,如果我们没有地方放置资讯,而这是变数输入的地方,从使用者取得资讯是没有用的。在之前的程式中 s 是一个变数,变数就如一个盒,可以储存一些资料,以下是一个程式,显示变数的范例:
a = 123.4
b23 = 'Spam'
first_name = "Bill"
b = 432
c = a + b
print "a + b is", c
print "first_name is", first_name
print "Sorted Parts, After Midnight or",b23
输出结果如下:
a + b is 555.4
first_name is Bill
Sorted Parts, After Midnight or Spam
变数会储存资料,以上程式中的变数为 a , b23, first_name,
b, 及 c,两个基本的类型为字串和数字,字串是一系列的字母、数字及其他字元。在本例中 b23
和 first_name 是储存字串的变数,Spam, Bill,
a + b is 及 first_name 是程式中的字串。字元会由 " 或
' 包围,其他类型的变数为数字。
好了,我们有了这些名为变数的盒子,以及会装入变数的资料,电脑会看到一行如 first_name = "Bill",而它会读取为
Put the string Bill 放入first_name 的盒子 (或变数)。其后它会看到
c = a + b 句子,并读取为 Put a + b 或 123.4 + 432
或 555.4 放入 c。
以下是另一个变数应用的范例:
a = 1
print a
a = a + 1
print a
a = a * 2
print a
输出结果如下:
1
2
4
即使在两边有同样的变数,电脑仍然会读取为:首先找出要储存的资料,再找出资料去了甚么地方。
在结束本章前最后一个程式:
num = input("Type in a Number: ")
str = raw_input("Type in a String: ")
print "num =", num
print "num is a ",type(num)
print "num * 2 =",num*2
print "str =", str
print "str is a ",type(str)
print "str * 2 =",str*2
输出结果为:
Type in a Number: 12.34
Type in a String: Hello
num = 12.34
num is a <type 'float'>
num * 2 = 24.68
str = Hello
str is a <type 'string'>
str * 2 = HelloHello
当num 取得 input, str 会取得 raw_input,
raw_input传回字串时,input 会传回数字。如您想使用者输入数字,可使用 input
,但如果您想使用者输入字串,可使用 raw_input。
程式第二部分使用 type,会告诉甚么是变数。数字是 int 或 float 类型
(分别是 'integer' 及 'floating point' 的缩写),字串是 string 类型。数字及浮点数可以由算术函数运作,而字串不会。留意
python 将数字乘整数时,预期的事情会如何发生。不过,当字串乘整数时,子串会加上其数量,即 str * 2 = HelloHello
。
字串的操作与数字的操作稍有不同,以下是一些互动模式范例,显示更多有关这些。
>>> "This"+" "+"is"+" joined."
'This is joined.'
>>> "Ha, "*5
'Ha, Ha, Ha, Ha, Ha, '
>>> "Ha, "*5+"ha!"
'Ha, Ha, Ha, Ha, Ha, ha!'
>>>
以下是一些字串操作的列表:
| 操作 | 符号 | 范例 |
| 重复 | * |
"i"*5 == "iiiii" |
| 结合 | + |
"Hello, "+"World!" == "Hello, World!" |
Rate_times.py
#This programs calculates rate and distance problems
print "Input a rate and a distance"
rate = input("Rate:")
distance = input("Distance:")
print "Time:",distance/rate
执行范例:
> python rate_times.py
Input a rate and a distance
Rate:5
Distance:10
Time: 2
> python rate_times.py
Input a rate and a distance
Rate:3.52
Distance:45.6
Time: 12.9545454545
#This program calculates the perimeter and area of a rectangle
print "Calculate information about a rectangle"
length = input("Length:")
width = input("Width:")
print "Area",length*width
print "Perimeter",2*length+2*width
执行范例:
> python area.py
Calculate information about a rectangle
Length:4
Width:3
Area 12
Perimeter 14
> python area.py
Calculate information about a rectangle
Length:2.53
Width:5.2
Area 13.156
Perimeter 15.46
temperature.py
#Converts Fahrenheit to Celsius
temp = input("Farenheit temperature:")
print (temp-32.0)*5.0/9.0
执行范例:
> python temperature.py
Farenheit temperature:32
0.0
> python temperature.py
Farenheit temperature:-40
-40.0
> python temperature.py
Farenheit temperature:212
100.0
> python temperature.py
Farenheit temperature:98.6
37.0
编写程式,从使用者取得两个字串变数和两个整数变数,结合 (连接它们而没有空间) 并显示字串,再在新一行将两个数字乘起来。
显示我们第一个控制结构,电脑一般以第一行开始,再往下看。控制结构会改变句式的次序,句式会被执行或决定会否某个句式会否执行。以下是使用 while 控制结构的程式源码:
a = 0
while a < 10:
a = a + 1
print a
以下是输出结果:
1
2
3
4
5
6
7
8
9
10
(当您的电脑成为一个五元的计算机后,您想它不会再差吧?) 那么程式会做些甚么?首先它会读取 a = 0 一行,并令它成为一个零,接着它会读取 while a < 10:因此电脑会查看 a < 10。电脑第一次看到 a is zero 这句式 ,因此它少于 10。换句话说,当 a 少于 10,电脑会在句式执行 tabbed。
以下是 while 应用的另一个范例:
a = 1
s = 0
print 'Enter Numbers to add to the sum.'
print 'Enter 0 to quit.'
while a != 0 :
print 'Current Sum:',s
a = input('Number? ')
s = s + a
print 'Total Sum =',s
我第一次执行这程式时,Python 会列印:
File "sum.py", line 3我忘了在 while 之后加上:,会有错误讯息投诉出现问题,并指出问题可能是有关
while a != 0
^
SyntaxError: invalid syntax
SPMquot^"。在问题解决后,以下是我在程式所做的东西:
Enter Numbers to add to the sum.
Enter 0 to quit.
Current Sum: 0
Number? 200
Current Sum: 200
Number? -15.25
Current Sum: 184.75
Number? -151.85
Current Sum: 32.9
Number? 10.00
Current Sum: 42.9
Number? 0
Total Sum = 42.9
留意如何列印'Total Sum =',s 只在结束时才执行。while 句式只会影响 tabbed 了的行 (亦称为缩排)。!= 表示不等于,因此 while a != 0 : 表示直至 a 是零执行其后 tabbed 了的句子。
现在我们有 while loops,很可能会令程式永远执行,一个容易的方法是编写程式如下:
while 1 == 1:
print "Help, I'm stuck in a loop."
这程式会一直输出 Help, I'm stuck in a loop. 直至世界末日或您停止它才会停下来。停止它的方式就是同时按 Control (或 Ctrl) 按钮及 `c' (字母),这就能将程式杀掉。 (注意:有时您需要在 Control C 之后按 enter。)
Fibonnacci.py
#This program calulates the fibonnacci sequence
a = 0
b = 1
count = 0
max_count = 20
while count < max_count:
count = count + 1
#we need to keep track of a since we change it
old_a = a
old_b = b
a = old_b
b = old_a + old_b
#Notice that the , at the end of a print statement keeps it
# from switching to a new line
print old_a,
输出结果:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
Password.py
# Waits until a password has been entered. Use control-C to break out with out
# the password
#Note that this must not be the password so that the
# while loop runs at least once.
password = "foobar"
#note that != means not equal
while password != "unicorn":
password = raw_input("Password:")
print "Welcome in"
执行范例:
Password:auo
Password:y22
Password:password
Password:open sesame
Password:unicorn
Welcome in
n = input("Number? ")
if n < 0:
print "The absolute value of",n,"is",-n
else:
print "The absolute value of",n,"is",n
以下就是我执行程式两次的结果:
Number? -34
The absolute value of -34 is 34
Number? 1
The absolute value of 1 is 1
当电脑看到这些源码时,它会做些甚么呢?首先会以 n = input("Number? ")句式要求使用者输入数字,接着会读取 if n < 0: 一行,如果 n 少于零,Python 会执行 print "The absolute value of",n,"is",-n 一行,否则 python 会执行 print "The absolute value of",n,"is",n 一行。
更正式地 Python 会查看 expression n < 0 属真属假,if 句式会由一组句式跟随,当表达式是真时就会执行,另一个选择就是 if 句式后的 else 句式,如果句式是假的 else 就会执行。
一个句式可以有不同的测试,以下是它们所有的列表:
| 运算符号 | 函数 |
< |
少于 |
<= |
少于或等于 |
> |
大于 |
>= |
大于或等于 |
== |
等于 |
!= |
不等于 |
<> |
不等于的另一种方式 |
if 指令的另一种特点是 elif 句式,它代表 for else if ,并表示如果原来的 if 句式是错误的,那么 elif 部分就是真的,以下是一个范例:
a = 0
while a < 10:
a = a + 1
if a > 5:
print a," > ",5
elif a <= 7:
print a," <= ",7
else:
print "Neither test was true"
以下是输出结果:
1 <= 7
2 <= 7
3 <= 7
4 <= 7
5 <= 7
6 > 5
7 > 5
8 > 5
9 > 5
10 > 5
留意 elif a <= 7 如何只在句式不真实时才会作测试,elif 允许在单一个 if 句式中进行多个测试。
#Plays the guessing game higher or lower
# (originally written by Josh Cogliati, improved by Quique)
#This should actually be something that is semi random like the
# last digits of the time or something else, but that will have to
# wait till a later chapter. (Extra Credit, modify it to be random
# after the Modules chapter)
number = 78
guess = 0
while guess != number :
guess = input ("Guess a number: ")
if guess > number :
print "Too high"
elif guess < number :
print "Too low"
print "Just right"
执行范例:
Guess a number:100
Too high
Guess a number:50
Too low
Guess a number:75
Too low
Guess a number:87
Too high
Guess a number:81
Too high
Guess a number:78
Just right
even.py
#Asks for a number.
#Prints if it is even or odd
number = input("Tell me a number: ")
if number % 2 == 0:
print number,"is even."
elif number % 2 == 1:
print number,"is odd."
else:
print number,"is very strange."
执行范例。
Tell me a number: 3
3 is odd.
Tell me a number: 2
2 is even.
Tell me a number: 3.14159
3.14159 is very strange.
average1.py
#keeps asking for numbers until 0 is entered.
#Prints the average value.
count = 0
sum = 0.0
number = 1 #set this to something that will not exit
# the while loop immediatly.
print "Enter 0 to exit the loop"
while number != 0:
number = input("Enter a number:")
count = count + 1
sum = sum + number
count = count - 1 #take off one for the last number
print "The average was:",sum/count
执行范例
Enter 0 to exit the loop
Enter a number:3
Enter a number:5
Enter a number:0
The average was: 4.0
Enter 0 to exit the loop
Enter a number:1
Enter a number:4
Enter a number:3
Enter a number:0
The average was: 2.66666666667
average2.py
#keeps asking for numbers until count have been entered.
#Prints the average value.
sum = 0.0
print "This program will take several numbers than average them"
count = input("How many numbers would you like to sum:")
current_count = 0
while current_count < count:
current_count = current_count + 1
print "Number ",current_count
number = input("Enter a number:")
sum = sum + number
print "The average was:",sum/count
执行范例
This program will take several numbers than average them
How many numbers would you like to sum:2
Number 1
Enter a number:3
Number 2
Enter a number:5
The average was: 4.0
This program will take several numbers than average them
How many numbers would you like to sum:3
Number 1
Enter a number:1
Number 2
Enter a number:4
Number 3
Enter a number:3
The average was: 2.66666666667
修改猜密码的程式,追纵使用者输入错误密码的次数,假如多于三次,就会列印 ``That must have been complicated.''。
编写一个程式,要求输入两个数字,如果数字的总和大于 100,会列印 ``That is big number''。
编写一个程式,要求使用者输入名称,如果他们输入您的名称,说 "That is a nice name",如果他们输入 "John Cleese" 或 "Michael Palin",告诉他们您对他们的感觉 ;),否则告诉他们 "You have a nice name"。
当我们开始编程,会发现要使程式运行,不是我们想像中的容易,我们需要进行除错,我仍记得当我知道生命的大部分时间就是要找出自己的程式的错处的那一刻。
- Maurice Wilkes discovers debugging, 1949
现在如果您感到程式有混乱,您可能发现程式有时会做一些您不想它做的事情,这是颇为普遍的。除错是找出电脑正在做甚么,以及您想它做甚么的过程,这可以是很花技巧的,我曾试过花了近一星期追查及解决一个问题,而问题是由某人将 y 当 x 所致。
本章会比之前的章节更抽像,请告诉我是否有用。
首要的事情 (这十分明显) 是要找出程式正确执行时会做些甚么,做一些测试情况,看看有甚么会发生。例如我有一个计算长方形周界的程式 (所有边界的长度总和),测试情况如下:
| 阔度 | 高度 | 周界 |
| 3 | 4 | 14 |
| 2 | 3 | 10 |
| 4 | 4 | 16 |
| 2 | 2 | 8 |
| 5 | 1 | 12 |
我现在于所有测试情况下执行我的程式,并查看程式是否如我预期所做的,如果不是,我需要找出电脑的所做的东西。
更普遍的是有些测试情况会运作,而有些却不能。如果是那种情况,您应该尝试和找出可以运作的有甚么共同的特点。例如以下是周界程式的输出结果 (您会在一分钟内看到源码):
Height: 3
Width: 4
perimeter = 15
Height: 2
Width: 3
perimeter = 11
Height: 4
Width: 4
perimeter = 16
Height: 2
Width: 2
perimeter = 8
Height: 5
Width: 1
perimeter = 8
留意首两个输入并不能运作,接着两个却没有问题,最后一个不能运作。尝试并找出可运作的有甚么共同的缺点,当您对问题的错误有头绪,要找出原因就容易一点了。如果有需要,可尝试更多测试条件。
下一个要做的东西是查看源程式码,在编程时其中一项要做的最重要事情就是查看源程式码,主要的方式就是查看源码。
查看程式就是在第一行开始,它会继续下去直至程式完成。While loops 及 if 句式表示有些行可能永不会执行,而有些行会执行很多次。在每一行您会找到 Python 做了些甚么。
现在就以简单的周界程式开始,不要输入,您现在就要读取它,而不是执行它。源程式码如下:
height = input("Height: ")
width = input("Width: ")
print "perimeter = ",width+height+width+width
问:第一行 Python 会执行甚么?
答:第一行永远都会执行,在这情况下是: height = input("Height: ")
问:那一行做甚么?
答:列印 Height: ,等候使用者输入一个数字,并将它放入变数 height。
问:接着执行那行是甚么?
答:一般来说,那是下一行 width = input("Width: ")
问:那一行做甚么?
答:列印 Width: ,等候使用者输入一个数字,并将它放入变数 width。
问:下一行执行的会是甚么?
答:当下一行比现有的行没有缩排太多或太少,那就是之后的一行,因此是: print "perimeter = ",width+height+width+width
(它可能亦会在现有一行执行一个函式,但那是之后的章节。)
问:那一行做些甚么?
答:首先它会列印 perimeter =,然后是 width+height+width+width 。
问:width+height+width+width 会正确计算周界吗?
答:现在看一看,长方形的周界是底 (阔) 加左边 (高) 加上 (阔)加右边 (高)。最后一个项目应该是右边的长度或高度。
问:您明白为甚么有时周界的计算会正确吗?
答:当阔度和高度相等时,计算就会正确。
下一个我们会研究源码的程式是会在萤幕印出 5 点的程式,不过程式的输出结果是:
. . . .
程式如下:
number = 5
while number > 1:
print ".",
number = number - 1
这个程式较复杂,因为它有缩排的部分 (或控制结构)。现在就开始吧。
问:第一行执行的是甚么?
答:档案第一行是: number = 5
问:它会做些甚么?
答:将数字 5 放在变数。
问:下一行是甚么?
答:下一行是 while number > 1:
问:它会做些甚么?
答:while 句式一般会寻找它们的表达式,如果表达式是真的,它们会做下一组缩排的源码,否则它们会略过下一组缩排的源码。
问:那么它现在会做些甚么?
答:如果 number > 1 是真的,就会执行接着那两行。
问:那么 number > 1 吗?
答:最后一个值会放入 number 的是 5 ,而 5 > 1 因此这是对的。
问:那么下一行是甚么?
答:由于 while 是真的,下一行是: print ".",
问:那一行会做甚么?
答:列印一点,而由于句式以 a 结束,下一行句式不会在第二行。
问:下一行是甚么?
答:number = number - 1 因为这是接着的行,而没有缩排的改变。
问:它做些甚么?
答:它计算 number - 1,那是 number (或 5) 的现有值减一,并使它成为新的 number 数值。因此基本上数字的值由 5 变为 4。
问:下一行是甚么?
答:缩排的层级减少,因此我们要查看控制结构的类型,那是一个 while loop,因此我们要返回
while 句式,就是 while number > 1:
问:它会做些甚么?
答:它会查看 number 的值,那就是 4,并将它与 1 比较,由于 4 > 1,while
loop 会继续。
问:下一行会是甚么?
答:由于while loop 是真的,下一行会是: print ".",
问:它会做甚么?
答:它会在该行列印第二点。
问:下一行会是甚么?
答:没有缩排改变,因此是: number = number - 1
问:它会做甚么?
答:它会计算 number (4) 的值,再减一,这样会得出 3,最后会令 3 成为 number 新的值
问:下一行会是甚么?
答:由于这缩排的改变是因 while loop 结束,下一行是: while number > 1:
问:它会做甚么?
答:它比较 number (3) 的值及 1. 3 > 1 ,因此 while loop
会继续。
问:下一行会是甚么?
答:由于 while loop 条件是真的,下一行是: print ".",
问:它会做甚么?
答:该行会列印第三点。
问:下一行会是甚么?
答:那是 number = number - 1
问:它会做甚么?
答:它会取得 number (3) 现有的值减一,并令 2 成为 number 的新值。
问:下一行会是甚么?
答:备份至 while loop 的开始:while number > 1:
问:它会做甚么?
答:它会比较 number (2) 的现有值及 1,由于 2 > 1 ,while loop
会继续。
问:下一行会是甚么?
答:由于 while loop 会继续:print ".",
问:它会做甚么?
答:它发现了生命、宇宙及所有东西的意义,说笑而已。(我要确定您是清醒的) 该行会在萤幕列印第四点。
问:下一行会是甚么?
答:那是 number = number - 1
问:它会做甚么?
答:取得 number (2) 的现有值减一,并使一成为 number 的新值。
问:下一行会是甚么?
答:备份至 while loop: while number > 1:
问:它会做甚么?
答:它会比较 number (1) 的现有值及一,由于 > 1 是错误的 (一并不比一大),while
loop 会离开。
问:下一行会是甚么?
答:由于 while loop 条件是错误的,下一行是 while loop 那一行是离开后的那一行,或: print
问:它会做甚么?
答:令萤幕往下一行。
问:为甚么程式不会列印五点?
答:loop 太快离开 1 点。
问:如何解决?
答:令 loop 较迟离开 1。
问:如何做到?
答:有几个方法也可以做到,一个方法是更改 while loop 为: while number > 0:
另一个方式是更改条件为: number >= 1 。还有一些其他方法。
您需要找出程式在做甚么,以及程式应该做甚么?找出两者的分别,除错是需要完成需要学习的技巧,假如您在一小时后仍未能找出它们的分别,可休息一会,与其他人谈谈有关的问题,或再仔细想想问题所在。过一会后回来,您可能会对问题有新的意见,祝您好运。
a = 23输出结果为:
b = -23
if a < 0:
a = -a
if b < 0:
b = -b
if a == b:
print "The absolute values of", a,"and",b,"are equal"
else:
print "The absolute values of a and b are different"
The absolute values of 23 and 23 are equal程式似乎有点重复, (编程员讨压重复的东西 (那是电脑的作用,不是吗?)) 幸好 Python 允许您建立函式移除重复。以下是重写的范例:
a = 23输出结果为:
b = -23
def my_abs(num):
if num < 0:
num = -num
return num
if my_abs(a) == my_abs(b):
print "The absolute values of", a,"and",b,"are equal"
else:
print "The absolute values of a and b are different"
The absolute values of 23 and -23 are equal这程式的主要功能是 def statement. def (define 的缩写) 开始一个函式定义, def 会以函式的名称 my_abs 跟随,接着而来的是( 由 num 参数跟随 (当呼叫函式时,num会从程式传入函式)。当使用函式时,会执行在 : 之后的句式。句式会继续,直至缩排的句式结束,或遇到 return。return 句式会将值传回函式呼叫的位置。
注意 a 和 b 的值没有改变,函式当然可以用来重复不会传回值的工作,以下是一些例子:
def hello():以下是输出结果:
print "Hello"
def area(width,height):
return width*height
def print_welcome(name):
print "Welcome",name
hello()
hello()
print_welcome("Fred")
w = 4
h = 5
print "width =",w,"height =",h,"area =",area(w,h)
Hello该范例只会显示更多您会以函数做的东西,注意您可以不使用参数或两个或更多参数,此外亦要留意当函数无须传回值时,return 是可有可无的。
Hello
Welcome Fred
width = 4 height = 5 area = 20
当然,当消除重复的源码时,在重复的源码中通常有变数,这些在 Python 上会以特别的方式处理。直至现在,我们看到的所有变数都是 global 变数,函式有一种特别的类型的变数称为 local 变数,这些变数只在函式执行时才会存在。当 local 变数与另一个变数有相同的名称,例如 global 变数,local 变数会隐藏其他变数。感到混乱了吗?希望下一个范例 (较有目的)能令您的概念清晰一点。
a_var = 10
b_var = 15
e_var = 25
def a_func(a_var):
print "in a_func a_var = ",a_var
b_var = 100 + a_var
d_var = 2*a_var
print "in a_func b_var = ",b_var
print "in a_func d_var = ",d_var
print "in a_func e_var = ",e_var
return b_var + 10
c_var = a_func(b_var)
print "a_var = ",a_var
print "b_var = ",b_var
print "c_var = ",c_var
print "d_var = ",d_var
输出结果为:
in a_func a_var = 15
in a_func b_var = 115
in a_func d_var = 30
in a_func e_var = 25
a_var = 10
b_var = 15
c_var = 125
d_var =
Traceback (innermost last):
File "separate.py", line 20, in ?
print "d_var = ",d_var
NameError: d_var
在本例中,当变数 a_var, b_var, 及 d_var 在 a_function
函式中,它们全都是 local 变数。当 return b_var + 10 句式执行时,它们全都停止存在。因为变数
a_var 是一个参数名称,它自动是 local 变数。变数 b_var 及 d_var 是
local 变数,因为它们出现在 b_var = 100 + a_var 及 d_var = 2*a_var
句式中函数等号的左边。
函数中的 a_var 为 15,因为函数称为 a_func(b_var)。由于那时 time b_var 是 15,传叫该函式为 a_func(15),这就会在 a_func 中时结束 a_var 设定为 15。
您会看到,当函式完成执行时, local 变数 a_var 及 b_var 会隐藏同一个名称的 global
变数。接着句式 print "a_var = ",a_var 会列印值为 10 而不是
15 ,因为隐藏 global 变数的 local 变数会消失。
另一项要留意的东西是在结尾的 NameError,这似乎是因为变数 d_var 自从 a_func 完成后便不在存在。所有 local 变数会在函式离开时删除,如果您想从函式取得一些东西,那么您需要使用 return。
最后要留意的一项东西是在a_func 中的 e_var 值保留不变,因为它不是一个参数,而它永不会出现在 a_func 函式中等号的左边。当 global 变数在函式中存取时,它在外界是 global 变数。
函数允许只存在函式中的 local 变数,而且可以将函数以外的其他变数隐藏。
TODO 将这部分移往新的一章,进阶函式。
现在我们会检查以下程式:
def mult(a,b):
if b == 0:
return 0
rest = mult(a,b - 1)
value = a + rest
return value
print "3*2 = ",mult(3,2)
基本上这程式会建立一个正的数字乘法函式 (那远比内置的乘法函式慢),然后透过使用这函式作示范。
问:程式首先会做甚么?
答:首先会做的是用以下几行定义的 mult 函式:
def mult(a,b):这会建立一个函式,取得两个参数,并在完成时传回一个值,之后这函式可以执行。
if b == 0:
return 0
rest = mult(a,b - 1)
value = a + rest
return value
问:接着会发生甚么?
答:函式后的下一行,会执行 print "3*2 = ",mult(3,2)。
问:这会做甚么?
答:它会列印 3*2 = 然后传回 mult(3,2)的值
问: mult(3,2) 会传回甚么?
答:我们需要查看 mult 函式找出。
问:接着会发生甚么?
答:变数 a 会取得 3 ,而变数 b 取得 2。
问:然后怎样?
答:if b == 0: 一行会被执行,由于 b 的值为 2,这是错误的,因此
return 0 一行会被略过。
问:然后又怎样?
答:rest = mult(a,b - 1)一行会被执行,这行会设定 local 变数 rest
为 mult(a,b - 1)的值。a 的值为 3,而 b 的值为 2,因此函式呼叫为
mult(3,1)。
问:那么 mult(3,1)的值是?
答:我们需要以参数 3 及 1 执行 mult 函式。
问:然后又会怎样?
答:新执行的函式中的 local 变数会被设定,因此 a 的值为 3,b 的值为 1。由于这些是 local 值,因此不会影响 a 及 b 之前的值。
问:然后呢?
答:由于 b 的值为 1,if 句式是假的,因此下一行变成 rest = mult(a,b -
1)。
问:这一行做些甚么?
答:这一行会为余下的指派 mult(3,0) 的值。
问:那么该值是甚么?
答:我们需要再执行函式一次才能找出,这次 a 的值为 3,b 的值为 0。
问:然后又怎样?
答:函式执行的第一行是 if b == 0:,b 的值为 0 ,因此下一行要执行的是
return 0
问:return 0 那一行会做甚么?
答:这行在函式中传回 0。
问:然后呢?
答:那么现在我们知道 mult(3,0) 的值为 0,现在我们知道 rest = mult(a,b
- 1) 一行做些甚么,因为我们以参数 3 及 0 执行 mult 函式。我们已完成执行 mult(3,0)
而且返回执行 mult(3,1) 。变数 rest 取得指派的值 0。
问:下一行会执行甚么?
答:接着会执行 value = a + rest 一行,函式执行时,a=3
而 rest=0 ,因此现在 value=3。
问:接着会发生甚么?
答:return value 一行会执行,这会从函式传回 3,这亦会从 mult (3,1) 函数离开,
return 执行后,我们会返回执行 mult(3,2)。
问:我们在 mult(3,2)哪里?
答:我们有的变数是 a=3 及 b=2,而且检查 rest =
mult(a,b - 1)一行。
问:因此现在会怎样?
答:变数 rest 取得 3,下一行 value = a + rest 设定值为
3+3 或 6。
问:因此现在会怎样?
答:下一行会执行,这会由函式传回 6,我们现在返回 print "3*2 = ",mult(3,2)
一行,现在可列印 6。
问:整体会怎样?
答:基本上我们使用两个事实计算两个数的乘数,第一个是任何数字乘 0 是 0 (x * 0 = 0),第二个是一个数字乘另一个数字等于第一个数字加第一个数字乘第二个数字减一 ( x * y = x + x * (y - 1))。因此会发生的是 3*2 首先转换成 3 + 3*1 ,接着 3*1 转换成 3 + 3*0。接着我们会知道任何数字乘 0 是 0,因此 3*0 是 0。然后我们会计算 3 + 3*0 是 3 + 0 就是 3。现在我们知道 3*1 是甚么,因此我们会计算 3 + 3*1 是 3 + 3 就是 6。
这是整个事情如何运作:
3*2
3 + 3*1
3 + 3 + 3*0
3 + 3 + 0
3 + 3
6
这些最后的两个部分最近写入,如果您有任何评论,找到任何错误或认为我需要更多/更清晰的解释,请电邮我。从前我知道令简单的事情复杂化,如果教学的余下部分是合理的,而本部分却不是,这可能是我的错误,感谢任何人让我知道。
factorial.py
#defines a function that calculates the factorial
def factorial(n):
if n <= 1:
return 1
return n*factorial(n-1)
print "2! = ",factorial(2)
print "3! = ",factorial(3)
print "4! = ",factorial(4)
print "5! = ",factorial(5)
输出结果:
2! = 2
3! = 6
4! = 24
5! = 120
temperature2.py
#converts temperature to fahrenheit or celsius
def print_options():
print "Options:"
print " 'p' print options"
print " 'c' convert from celsius"
print " 'f' convert from fahrenheit"
print " 'q' quit the program"
def celsius_to_fahrenheit(c_temp):
return 9.0/5.0*c_temp+32
def fahrenheit_to_celsius(f_temp):
return (f_temp - 32.0)*5.0/9.0
choice = "p"
while choice != "q":
if choice == "c":
temp = input("Celsius temperature:")
print "Fahrenheit:",celsius_to_fahrenheit(temp)
elif choice == "f":
temp = input("Fahrenheit temperature:")
print "Celsius:",fahrenheit_to_celsius(temp)
elif choice != "q":
print_options()
choice = raw_input("option:")
执行范例:
> python temperature2.py
Options:
'p' print options
'c' convert from celsius
'f' convert from fahrenheit
'q' quit the program
option:c
Celsius temperature:30
Fahrenheit: 86.0
option:f
Fahrenheit temperature:60
Celsius: 15.5555555556
option:q
area2.py
#By Amos Satterlee
def hello():
print 'Hello!'
def area(width,height):
return width*height
def print_welcome(name):
print 'Welcome,',name
name = raw_input('Your Name: ')
hello(),
print_welcome(name)
print 'To find the area of a rectangle,'
print 'Enter the width and height below.'
w = input('Width: ')
while w <= 0:
print 'Must be a positive number'
w = input('Width: ')
h = input('Height: ')
while h <= 0:
print 'Must be a positive number'
h = input('Height: ')
print 'Width =',w,' Height =',h,' so Area =',area(w,h)
执行范例:
Your Name: Josh
Hello!
Welcome, Josh
To find the area of a rectangle,
Enter the width and height below.
Width: -4
Must be a positive number
Width: 4
Height: 3
Width = 4 Height = 3 so Area = 12
重新编写 area.py 在 3.2 完成的程式,为一个正方形、长方形及圆形 (3.14 * radius**2) 的面积做一个独立的函式,这程式应该包括一个选单介面。
which_one = input("What month (1-12)? ")
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July',\
'August', 'September', 'October', 'November', 'December']
if 1 <= which_one <= 12:
print "The month is",months[which_one - 1]
以下是一个输出范例:
What month (1-12)? 3
The month is March
在本例中 months 是一个 list,months 以 months = ['January',
'February', 'March', 'April', 'May', 'June', 'July',\ 'August',
'September', 'October', 'November', 'December'] 来定义 (留意 \
可以用作分割一长行)。[ 及 ]以逗号 (``,'') 开始及结束
list,分开 list 项目。list 在 months 中使用[which_one - 1],一个 list 包含由零开始的项目,换句话说,您应该使用
months[0],为 list 给予一个数字,它会传回储存在该位置的值。
if 1 <= which_one <= 12: 句式只会当 which_one 在一之十二中间才会是真实的 (换句话说,如果您曾在代数看过,这就是您想要的)。
Lists 可以被视为一系统的盒子,例如由demolist = ['life',42, 'the universe', 6,'and',7] 建立的盒子会如下:
| 盒子号码 | 0 | 1 | 2 | 3 | 4 | 5 |
| demolist | `life' | 42 | `the universe' | 6 | `and' | 7 |
每个盒子都由其数字参照,因此 demolist[0] 句式会取得 'life',demolist[1] 会取得 42,如此类推,直至 demolist[5] 取得 7。
demolist = ['life',42, 'the universe', 6,'and',7]
print 'demolist = ',demolist
demolist.append('everything')
print "after 'everything' was appended demolist is now:"
print demolist
print 'len(demolist) =', len(demolist)
print 'demolist.index(42) =',demolist.index(42)
print 'demolist[1] =', demolist[1]
#Next we will loop through the list
c = 0
while c < len(demolist):
print 'demolist[',c,']=',demolist[c]
c = c + 1
del demolist[2]
print "After 'the universe' was removed demolist is now:"
print demolist
if 'life' in demolist:
print "'life' was found in demolist"
else:
print "'life' was not found in demolist"
if 'amoeba' in demolist:
print "'amoeba' was found in demolist"
if 'amoeba' not in demolist:
print "'amoeba' was not found in demolist"
demolist.sort()
print 'The sorted demolist is ',demolist
输出结果为:
demolist = ['life', 42, 'the universe', 6, 'and', 7]
after 'everything' was appended demolist is now:
['life', 42, 'the universe', 6, 'and', 7, 'everything']
len(demolist) = 7
demolist.index(42) = 1
demolist[1] = 42
demolist[ 0 ]= life
demolist[ 1 ]= 42
demolist[ 2 ]= the universe
demolist[ 3 ]= 6
demolist[ 4 ]= and
demolist[ 5 ]= 7
demolist[ 6 ]= everything
After 'the universe' was removed demolist is now:
['life', 42, 6, 'and', 7, 'everything']
'life' was found in demolist
'amoeba' was not found in demolist
The sorted demolist is [6, 7, 42, 'and', 'everything', 'life']
这范例使用整套新的函式,留意您只能列印整套 list,接着 append 函式是用来新增项目至 list
的结尾,len 传回 list中项目的数目。一个 list 中有效的 indexes (用在 [] 内的数字)由 0 至
len - 1,index 函式会告诉您项目在 list 中的第一个位置,留意 demolist.index(42)
如何传回 1,而当 demolist[1] 执行时会传回 42。#Next we will loop
through the list 一行只是编程员的一个备忘 (亦称为评论)。Python 会忽略任何以 #
开始的行,接着的行是:
c = 0建立一个变数 c ,以 0 开始,并递增直至到达 list 的最后 index,同时 print 句式会列印 list 的每个元素。
while c < len(demolist):
print 'demolist[',c,']=',demolist[c]
c = c + 1
del 指令可用来移除 list 中特定的元素,下几行会使用 in 操作符测试元素是否在 list
中 。
sort 函式会将 list 排序,如果您需要一个从小至大或顺字母排序的 list,那是很有用的,留意这会将 list
重新排列。
总结 list 有以下的操作:
| 范例 | 解释 |
| list[2] | 在 index 2 存取元素 |
| list[2] = 3 | 设定index 2 的元素为 3 |
| del list[2] | 在 index 2 移除元素 |
| len(list) | 传回 list 的长度 |
| "value" in list | 如果 "value" 是 list 中的元素就是真实的 |
| "value" not in list | 如果 "value" 不是 list 中的元素就是真实的 |
| list.sort() | 排列 list |
| list.index("value") | 传回 "value" 第一次出现的 index |
| list.append("value") | 在 list 的结尾新增 "value" 元素 |
下一个范例会以更有用的方法使用这些功能:
menu_item = 0
list = []
while menu_item != 9:
print "--------------------"
print "1. Print the list"
print "2. Add a name to the list"
print "3. Remove a name from the list"
print "4. Change an item in the list"
print "9. Quit"
menu_item = input("Pick an item from the menu: ")
if menu_item == 1:
current = 0
if len(list) > 0:
while current < len(list):
print current,". ",list[current]
current = current + 1
else:
print "List is empty"
elif menu_item == 2:
name = raw_input("Type in a name to add: ")
list.append(name)
elif menu_item == 3:
del_name = raw_input("What name would you like to remove: ")
if del_name in list:
item_number = list.index(del_name)
del list[item_number]
#The code above only removes the first occurance of
# the name. The code below from Gerald removes all.
#while del_name in list:
# item_number = list.index(del_name)
# del list[item_number]
else:
print del_name," was not found"
elif menu_item == 4:
old_name = raw_input("What name would you like to change: ")
if old_name in list:
item_number = list.index(old_name)
new_name = raw_input("What is the new name: ")
list[item_number] = new_name
else:
print old_name," was not found"
print "Goodbye"
以下是输出结果的一部分:
--------------------
1. Print the list
2. Add a name to the list
3. Remove a name from the list
4. Change an item in the list
9. Quit
Pick an item from the menu: 2
Type in a name to add: Jack
Pick an item from the menu: 2
Type in a name to add: Jill
Pick an item from the menu: 1
0 . Jack
1 . Jill
Pick an item from the menu: 3
What name would you like to remove: Jack
Pick an item from the menu: 4
What name would you like to change: Jill
What is the new name: Jill Peters
Pick an item from the menu: 1
0 . Jill Peters
Pick an item from the menu: 9
Goodbye
那是一个很长的程式,现在就看一看源程式码,list = [] 一行会令变数 list 成为没有项目的 list
(或元素)。下一个重要的行是 while menu_item != 9:,这行会开始一个 loop,允许这程式的选单系统,下几行会显示一个选单,并决定执行程式哪部分。
该部分:
current = 0检查 list 并列印每个名字,
if len(list) > 0:
while current < len(list):
print current,". ",list[current]
current = current + 1
else:
print "List is empty"
len(list_name) 会告诉您 list 有多少个项目,如果
len 传回 0 ,list 就是空白的。
拉着几行之后,list.append(name) 句式会出现,它会使用 append 函式新增项目至 list 的结尾。跳过另外两行,留意本部分的源码:
item_number = list.index(del_name)这儿 index 函式是用来找出 index 值,在之后会用来移除项目。
del list[item_number]
del list[item_number]
是用来移除 list 的元素。
下一部分:
old_name = raw_input("What name would you like to change: ")
if old_name in list:
item_number = list.index(old_name)
new_name = raw_input("What is the new name: ")
list[item_number] = new_name
else:
print old_name," was not found"
使用 index 找出 item_number,再将 new_name
放在 old_name。
恭喜您,您已掌握了 lists,您现在已对该语言有足够的认识,可以做任何电脑可做的计算了 (这在技术上称为 Turing-Completness)。当然,仍然有很多功能可以令您的生括更容易。
test.py
## This program runs a test of knowledge
true = 1
false = 0
# First get the test questions
# Later this will be modified to use file io.
def get_questions():
# notice how the data is stored as a list of lists
return [["What color is the daytime sky on a clear day?","blue"],\
["What is the answer to life, the universe and everything?","42"],\
["What is a three letter word for mouse trap?","cat"]]
# This will test a single question
# it takes a single question in
# it returns true if the user typed the correct answer, otherwise false
def check_question(question_and_answer):
#extract the question and the answer from the list
question = question_and_answer[0]
answer = question_and_answer[1]
# give the question to the user
given_answer = raw_input(question)
# compare the user's answer to the testers answer
if answer == given_answer:
print "Correct"
return true
else:
print "Incorrect, correct was:",answer
return false
# This will run through all the questions
def run_test(questions):
if len(questions) == 0:
print "No questions were given."
# the return exits the function
return
index = 0
right = 0
while index < len(questions):
#Check the question
if check_question(questions[index]):
right = right + 1
#go to the next question
index = index + 1
#notice the order of the computation, first multiply, then divide
print "You got ",right*100/len(questions),"% right out of",len(questions)
#now lets run the questions
run_test(get_questions())
输出范例:
What color is the daytime sky on a clear day?green
Incorrect, correct was: blue
What is the answer to life, the universe and everything?42
Correct
What is a three letter word for mouse trap?cat
Correct
You got 66 % right out of 3
扩充 test.py 程式,令它有进行测试、检视问题及答案清单、离开选项的选单。此外亦加一个问题: ‘一台真正先进的机器会发出甚么声音?’答案为 "ping"。
onetoten = range(1,11)输出结果如下:
for count in onetoten:
print count
1输出结果十分相似,但程源码很不同。第一行使用 range 函式,range 函式使用两个参数如 this range(start,finish)。start 是所产生的第一个数字,finish 比上一个数字大一,留意这程式可以较短的方式做到:
2
3
4
5
6
7
8
9
10
for count in range(1,11):以下是一些例子,显示 range 指令的功能:
print count
>>> range(1,10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(-32, -20)
[-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21]
>>> range(5,21)
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
>>> range(21,5)
[]
下一行 for count in onetoten: 使用 for 控制结构,一个 for
控制结构像 list 中的 for 变数。list从第一个元素一直看到最后一个,由于 for
会经历 list 的每个元素,它会将每个放入变数。这会容许在 for loop 执行的连续时间使用变数,以下是示范的另一个范例
(您不用输入这个):
demolist = ['life',42, 'the universe', 6,'and',7,'everything']输出结果是:
for item in demolist:
print "The Current item is:",
print item
The Current item is: life留意 for loop 如何经历,并在 list 中的每个元素设定项目。 (留意程式如何做到,如果您不想 print 往下一行,在句式结尾新增一个逗号 (即是,如果您想在该行列印其他东西) ) 那么, for 有甚么好处呢? (叹息) 第一个用途是经历 list 中的所有元素,并为每一个做一点东西。以下是将所有元素加起来的快捷方法:
The Current item is: 42
The Current item is: the universe
The Current item is: 6
The Current item is: and
The Current item is: 7
The Current item is: everything
list = [2,4,6,8]输出结果只有:
sum = 0
for num in list:
sum = sum + num
print "The sum is: ",sum
The sum is: 20或您可以编写一个程式,找出 list 中的任何重复,就如这程式一样:
list = [4, 5, 7, 8, 9, 1,0,7,10]而为了好的习惯:
list.sort()
prev = list[0]
del list[0]
for item in list:
if prev == item:
print "Duplicate of ",prev," Found"
prev = item
Duplicate of 7 Found好,那么它如何运作呢?以下是特别的除错版本,帮助您明白 (您无须输入这些):
l = [4, 5, 7, 8, 9, 1,0,7,10]输出结果为:
print "l = [4, 5, 7, 8, 9, 1,0,7,10]","\tl:",l
l.sort()
print "l.sort()","\tl:",l
prev = l[0]
print "prev = l[0]","\tprev:",prev
del l[0]
print "del l[0]","\tl:",l
for item in l:
if prev == item:
print "Duplicate of ",prev," Found"
print "if prev == item:","\tprev:",prev,"\titem:",item
prev = item
print "prev = item","\t\tprev:",prev,"\titem:",item
l = [4, 5, 7, 8, 9, 1,0,7,10] l: [4, 5, 7, 8, 9, 1, 0, 7, 10]我将那么多 print 句式放在源码的原因是,让您可以看到每一行在做甚么。 (顺带一提,如果您不能找出程式不运作的原因,尝试加入很多 print 句式,您会看到有甚么发生) 首先程式以一个沉闷的旧清单开始,然后程式会排列清单,那么任何重复都会放入去。然后程式会启用之前的变数,接着清单的第一个元素会被删除,因此第一个项目不会错误地视为重复的。接着会进入一个 for loop,清单每一个项目都会被选取,查看是否与之前的一样。如果找到重复的,prev 会更改,那么下一次执行 for loop 时,prev 就是现有项目之前的项目。不出所料,7 就会是重复的。(留意如何使用
l.sort() l: [0, 1, 4, 5, 7, 7, 8, 9, 10]
prev = l[0] prev: 0
del l[0] l: [1, 4, 5, 7, 7, 8, 9, 10]
if prev == item: prev: 0 item: 1
prev = item prev: 1 item: 1
if prev == item: prev: 1 item: 4
prev = item prev: 4 item: 4
if prev == item: prev: 4 item: 5
prev = item prev: 5 item: 5
if prev == item: prev: 5 item: 7
prev = item prev: 7 item: 7
Duplicate of 7 Found
if prev == item: prev: 7 item: 7
prev = item prev: 7 item: 7
if prev == item: prev: 7 item: 8
prev = item prev: 8 item: 8
if prev == item: prev: 8 item: 9
prev = item prev: 9 item: 9
if prev == item: prev: 9 item: 10
prev = item prev: 10 item: 10
\t 列印 tab。)
另一种使用 for loops 方法是做一些东西数次,以下是一些源码,列印 Fibonacci 系统的首 11 个数字:
a = 1出人意表的结果是:
b = 1
for c in range(1,10):
print a,
n = a + b
a = b
b = n
1 1 2 3 5 8 13 21 34所有可以 for loops 完成的东西亦可以 while loops 完成,但 for loops 会更容易经历清单中的所有元素,或做一些东西数次。
a = 6输出结果如下:
b = 7
c = 42
print 1, a == 6
print 2, a == 7
print 3,a == 6 and b == 7
print 4,a == 7 and b == 7
print 5,not a == 7 and b == 7
print 6,a == 7 or b == 7
print 7,a == 7 or b == 6
print 8,not (a == 7 and b == 6)
print 9,not a == 7 and b == 6
1 1发生甚么呢?程式包含了很多有趣好看的 print 句式,每个 print 句式会列印一个数字及一个表达式,数字是用来协助追纵我所处理的句式,留意每个表达式如何最终变成 0 或 1,在 Python,false 会写入为 0,true 会写入为 1,如下:
2 0
3 1
4 0
5 1
6 1
7 0
8 1
9 0
print 1, a == 6这会如预期分别列印一个 1 及一个 0,因为第一个是 true 而第二个是 false。第三个 print,
print 2, a == 7
print 3,a
== 6 and b == 7 是有一点不同。如果之前的两个句式及之后的句式是 true,整个表达式都是 true,否则整个表达式都是
false。下一行 print 4,a == 7 and b == 7 显示如果 and 表达式部分为 false,整个表达式都会是
false。 and 的行为可以总结如下:
| 表达式 | 结果 |
| true and true | true |
| true and false | false |
| false and true | false |
| false and false | false |
留意如果第一个表达式为 false,Python 不会检查第二个表达式,因为它知道整个表达式都会是 false。
下一行,print 5,not a == 7 and b == 7 使用 not 操作符,
not 只会给予表达式的相反 (表达式可以重写为 print 5,a != 7 and b == 7),如下表:
| 表达式 | 结果 |
| not true | false |
| not false | true |
接着的两行,print 6,a == 7 or b == 7 及 print 7,a == 7 or
b == 6 使用 or 操作符。如果第一个表达式为 true,或第二个表达式为 true 或两者都是 true,or
操作符会传回 true。如果两者都不是 true,它会传回 false,如下表:
| 表达式 | 结果 |
| true or true | true |
| true or false | true |
| false or true | true |
| false or false | false |
留意如果第一个表达式是 true,Python 不会检查第二个表达式,因为它知道整个表达式都是 true。如果至少表达式的一半为 true,or 就是 true,这就能运作。第一部分是 true,因此第二部分可以是 false 或 true,但整个表达式仍然是 true 的。
接着两行 print 8,not (a == 7 and b == 6) 及 print 9,not
a == 7 and b == 6 显示括弧可以用来将表达式群组,并迫使一部分首先评估。留意括弧会将表达式从 false 改为 true,这是因为括弧强使
not 套用至整个表达式,而不是单单 a == 7 那部分。
以下是使用 boolean expression 的范例:
list = ["Life","The Universe","Everything","Jack","Jill","Life","Jill"]
#make a copy of the list. See the More on Lists chapter to explain what
#[:] means.
copy = list[:]
#sort the copy
copy.sort()
prev = copy[0]
del copy[0]
count = 0
#go through the list searching for a match
while count < len(copy) and copy[count] != prev:
prev = copy[count]
count = count + 1
#If a match was not found then count can't be < len
#since the while loop continues while count is < len
#and no match is found
if count < len(copy):
print "First Match: ",prev
输出结果如下:
First Match: Jill
这个程式会透过继续检查符合 while count < len(copy and copy[count] 这句式而运作,当其中一个 count大于复本最后的 index,或找到符合的句式时,它不会再是 true,因此 loop 会离开。if 只是检查确定 while 会因找到符合的句式而离开。
另一个 and 的‘技巧’会在本例中使用,假如您查看列表,并留意到第三个记录是 ``false and won't check''。如果 count >= len(copy) (换句话说 count < len(copy)为 false),那么 copy[count] 就永不会被检查。这是因为 Python 知道如果第一个为 false,那么两者都不能为 true。这称为短路,如果 and 的第二部会导致错误或有东西出错,这是很有用的。我使用第 一个表达式 count < len(copy)) count 是 copy 的一个有效的index 。(如果您不相信我而移除 `Jill' 及 `Life',检查它仍能运作,再逆转 count < len(copy) 及 copy[count] != prev to copy[count] != prev and count < len(copy)的次序)。
当您需要同时检查两个或更多东西时,就可以使用 Boolean expressions。
password1.py
## This programs asks a user for a name and a password.
# It then checks them to make sure the the user is allowed in.
name = raw_input("What is your name? ")
password = raw_input("What is the password? ")
if name == "Josh" and password == "Friday":
print "Welcome Josh"
elif name == "Fred" and password == "Rock":
print "Welcome Fred"
else:
print "I don't know you."
执行范例
What is your name? Josh
What is the password? Friday
Welcome Josh
What is your name? Bill
What is the password? Money
I don't know you.
编写程式,让使用者猜您的名字,但在程式结束前他们只有三次机会。
def print_menu():以下是我的输出结果:
print '1. Print Phone Numbers'
print '2. Add a Phone Number'
print '3. Remove a Phone Number'
print '4. Lookup a Phone Number'
print '5. Quit'
numbers = {}
menu_choice = 0
print_menu()
while menu_choice != 5:
menu_choice = input("Type in a number (1-5):")
if menu_choice == 1:
print "Telephone Numbers:"
for x in numbers.keys():
print "Name: ",x," \tNumber: ",numbers[x]
elif menu_choice == 2:
print "Add Name and Number"
name = raw_input("Name:")
phone = raw_input("Number:")
numbers[name] = phone
elif menu_choice == 3:
print "Remove Name and Number"
name = raw_input("Name:")
if numbers.has_key(name):
del numbers[name]
else:
print name," was not found"
elif menu_choice == 4:
print "Lookup Number"
name = raw_input("Name:")
if numbers.has_key(name):
print "The number is",numbers[name]
else:
print name," was not found"
elif menu_choice != 5:
print_menu()
1. Print Phone Numbers这程式与本章较早前的 name list 相似,以下是程式如何运作,首先 function
2. Add a Phone Number
3. Remove a Phone Number
4. Lookup a Phone Number
5. Quit
Type in a number (1-5):2
Add Name and Number
Name:Joe
Number:545-4464
Type in a number (1-5):2
Add Name and Number
Name:Jill
Number:979-4654
Type in a number (1-5):2
Add Name and Number
Name:Fred
Number:132-9874
Type in a number (1-5):1
Telephone Numbers:
Name: Jill Number: 979-4654
Name: Joe Number: 545-4464
Name: Fred Number: 132-9874
Type in a number (1-5):4
Lookup Number
Name:Joe
The number is 545-4464
Type in a number (1-5):3
Remove Name and Number
Name:Fred
Type in a number (1-5):1
Telephone Numbers:
Name: Jill Number: 979-4654
Name: Joe Number: 545-4464
Type in a number (1-5):5
print_menu
会被定义, print_menu 只列印一个选单供程式之后使用两之,接着是有趣的 line numbers
= {},该行所做的就是告诉 Python,numbers 是一个字典,接着的几行只是令选单运作,那几行如下:
for x in numbers.keys():检查字典并列印所有资讯,numbers.keys() 函式会传回一个清单,之后由for loop使用,由 keys 传回的清单不是在任何特定的次序,因此如果您想它顺字母次序,必须先排序。与清单相似,numbers[x] 句式用来存取字典中特定的成员,当然在这情况下 x 是一个字串。接着一行 numbers[name] = phone 为字典新增一个名字及电话号码。假如名字已在字典中, phone 会取代之前的资料,接着几行如下:
print "Name: ",x," \tNumber: ",numbers[x]
if numbers.has_key(name):查看名字是否在字典中,如果是就移除它。如果名字是数字,
del numbers[name]
numbers.has_key(name) 函式会传回 true,否则会传回false。
del numbers[name] 一行会移除 key 的名称及相关的值,该数行如下:
if numbers.has_key(name):查看字典是否有特定的 key ,如果有就列印与它相关的数字。最后如果选单选项无效,它会重新列印选单供您查看:
print "The number is",numbers[name]
重温: 字典有键及值,键可以是字串或数字,键指向值,值可以是变数的任何类型 (包括清单或甚至字典 (那些字典或清单当然会包括字典或清单本身 (可怕吧? :) ))。以下是在字典中使用清单的范例:
max_points = [25,25,50,25,100]
assignments = ['hw ch 1','hw ch 2','quiz ','hw ch 3','test']
students = {'#Max':max_points}
def print_menu():
print "1. Add student"
print "2. Remove student"
print "3. Print grades"
print "4. Record grade"
print "5. Print Menu"
print "6. Exit"
def print_all_grades():
print '\t',
for i in range(len(assignments)):
print assignments[i],'\t',
keys = students.keys()
keys.sort()
for x in keys:
print x,'\t',
grades = students[x]
print_grades(grades)
def print_grades(grades):
for i in range(len(grades)):
print grades[i],'\t\t',
以下是输出范例:
print_menu()
menu_choice = 0
while menu_choice != 6:
menu_choice = input("Menu Choice (1-6):")
if menu_choice == 1:
name = raw_input("Student to add:")
students[name] = [0]*len(max_points)
elif menu_choice == 2:
name = raw_input("Student to remove:")
if students.has_key(name):
del students[name]
else:
print "Student: ",name," not found"
elif menu_choice == 3:
print_all_grades()
elif menu_choice == 4:
print "Record Grade"
name = raw_input("Student:")
if students.has_key(name):
grades = students[name]
print "Type in the number of the grade to record"
print "Type a 0 (zero) to exit"
for i in range(len(assignments)):
print i+1,' ',assignments[i],'\t',
print_grades(grades)
which = 1234
while which != -1:
which = input("Change which Grade:")
which = which-1
if 0 <= which < len(grades):
grade = input("Grade:")
grades[which] = grade
elif which != -1:
print "Invalid Grade Number"
else:
print "Student not found"
elif menu_choice != 6:
print_menu()
1. Add student
2. Remove student
3. Print grades
4. Record grade
5. Print Menu
6. Exit
Menu Choice (1-6):3
hw ch 1 hw ch 2 quiz hw ch 3 test
#Max 25 25 50 25 100
Menu Choice (1-6):6
1. Add student
2. Remove student
3. Print grades
4. Record grade
5. Print Menu
6. Exit
Menu Choice (1-6):1
Student to add:Bill
Menu Choice (1-6):4
Record Grade
Student:Bill
Type in the number of the grade to record
Type a 0 (zero) to exit
1 hw ch 1 2 hw ch 2 3 quiz 4 hw ch 3 5 test
0 0 0 0 0
Change which Grade:1
Grade:25
Change which Grade:2
Grade:24
Change which Grade:3
Grade:45
Change which Grade:4
Grade:23
Change which Grade:5
Grade:95
Change which Grade:0
Menu Choice (1-6):3以下是程式运作的方式,基本上 students 变数是一个字典,以学生的名字为键,他们的成绩为值。首二行只是建立两个清单,下一行
hw ch 1 hw ch 2 quiz hw ch 3 test
#Max 25 25 50 25 100
Bill 25 24 45 23 95
Menu Choice (1-6):6
students = {'#Max':max_points} 建立一个新的字典,以 #Max
为键,值设定为 [25,25,50,25,100] (因为在建立 assignments 后,那就是 max_points
) (我使用的 #Max since # 键已排序在任何字母字元之首)。 接着定义
print_menu,接着 print_all_grades 函式在以下几行中定义:
def print_all_grades():留意键如何首先从 students 字典中取得,而 keys 函式在 keys = students.keys()一行, keys 是一个清单,因此该清单所有函式都可以使用。接着键会在 keys.sort() 一行排序,因为它是一个清单。 for 用来经历所有键,分数储存在字典的清单中,因此 assignment grades = students[x] 给予 grades储存在 x 键的清单,
print '\t',
for i in range(len(assignments)):
print assignments[i],'\t',
keys = students.keys()
keys.sort()
for x in keys:
print x,'\t',
grades = students[x]
print_grades(grades)
print_grades 函式只会列印一个清单,而且在其后定义几行。
程式之后几行会落实选单不同的选项,students[name] = [0]*len(max_points) 一行为学生的名字键新增一个学生,
[0]*len(max_points) 记号只是建立 0 的阵列,那是与 max_points
清单的长度一样。
移除学生记录只是删除一个学,与电话簿范例相似。记录分数选项更复杂一点,分数会从 grades = students[name]一行提取,取得学生名称的分数的参照。分数其后会记录在 grades[which] = grade 一行中,您可能会留意到分数永不会放在 students 字典中 (就如在 no students[name] = grades)。遗漏了句子的原因是分数其实是 students[name] 的另一个名称,因此更改 grades 会更改 student[name]。
字典为连结键及值提供一种很容易的方式,这可以很容易追纵连结不同键的资料。
import calendar以下是输出结果的一部分:
year = input("Type in the year number:")
calendar.prcal(year)
Type in the year number:2001(我略过部分输出结果,但我想您已知道意思) 那么程式会做些甚么?第一行 import calendar 使用新的指令 import,import 指令会载入一个模组 (在本例中是 calendar 模组)。要查看标准模组中的可用指令,可看看 python 的程式库参照 (如果您下载了它) 或往 http://www.python.org/doc/current/lib/lib.html 。 calendar 模组在 5.9 描述,如果您查看文档,会有一个叫 prcal 的函式,列印一年的月历。calendar.prcal(year) 一行使用该函式,总括而言是使用一个import 模组,然后在模组中使用 module_name.function。另一种方法是编写程式:
2001
January February March
Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7 1 2 3 4 1 2 3 4
8 9 10 11 12 13 14 5 6 7 8 9 10 11 5 6 7 8 9 10 11
15 16 17 18 19 20 21 12 13 14 15 16 17 18 12 13 14 15 16 17 18
22 23 24 25 26 27 28 19 20 21 22 23 24 25 19 20 21 22 23 24 25
29 30 31 26 27 28 26 27 28 29 30 31
from calendar import prcal这个版本会从模组输入一个特定的函式,以下是另一个使用 Python Library 的程式 (将它名为类似 clock.py) (同时按 Ctrl 及 'c' 键可杀掉程式):
year = input("Type in the year number:")
prcal(year)
from time import time, ctime输出结果为:
prev_time = ""
while(1):
the_time = ctime(time())
if(prev_time != the_time):
print "The time is:",ctime(time())
prev_time = the_time
The time is: Sun Aug 20 13:40:04 2000输出当然是无尽的,因此我取消了它 (否则输出结果会继续,直至按 Ctrl+C 为止)。程式只会做一个无限的 loop ,而每次会作检查,如果时间有变就会列印出来。留意 import 句式后多个名称会在 from time import time, ctime 一行使用。
The time is: Sun Aug 20 13:40:05 2000
The time is: Sun Aug 20 13:40:06 2000
The time is: Sun Aug 20 13:40:07 2000
Traceback (innermost last):
File "clock.py", line 5, in ?
the_time = ctime(time())
KeyboardInterrupt
Python Library 包含很多有用的函式,这些函式会让您的程式有更多功能,而它们很多会简化 Python 编程。
重写 5.2 部分的 high_low.py 程式,使用那时间的最后两个数字为 'random' 数字。
以下是使用 indexing 存取 list 中的单一元素:
>>> list = ['zero','one','two','three','four','five']所有那些范例您应该似曾相识,如果您想list 中的第一个项目只查看 index 0,第二个项目是 index 1 ,如此类推。不过如果您想要列表中的最后项目又如何?一种方式是使用
>>> list[0]
'zero'
>>> list[4]
'four'
>>> list[5]
'five'
len 函式如 list[len(list)-1] 。这种方式可以运作,因为
len 函式通常会传回最后一个 index 加一,最后第二个会是 list[len(list)-2]。有更容易的方法做到,在
Python 中最后一个项目通常是 index -1,最后第二个是 index -2,如此类推,以下是更多范例:
>>> list[len(list)-1]结果 list 中的任何项目可以两种方式做索引:由前面至后面。
'five'
>>> list[len(list)-2]
'four'
>>> list[-1]
'five'
>>> list[-2]
'four'
>>> list[-6]
'zero'
另一种有用的方式是令 lists 的一部分使用 slices,以下是另一个范例,令您知道它有甚么用途:
>>> list = [0,'Fred',2,'S.P.A.M.','Stocking',42,"Jack","Jill"]Slices 是用来传回一个 list 的部分,slice operator 是以
>>> list[0]
0
>>> list[7]
'Jill'
>>> list[0:8]
[0, 'Fred', 2, 'S.P.A.M.', 'Stocking', 42, 'Jack', 'Jill']
>>> list[2:4]
[2, 'S.P.A.M.']
>>> list[4:7]
['Stocking', 42, 'Jack']
>>> list[1:5]
['Fred', 2, 'S.P.A.M.', 'Stocking']
list[first_index:following_index]形式。
slice 从 first_index 往following_index 前的 index。您可以使用两种
indexing:
>>> list[-4:-2]另一个 slices 的技巧是未指明的 index,如果第一个 index 未有指明,会假设是清单的开始。如果随后的 index 未有指明,会假设是清单的所有余下部分。以下是一些范例:
['Stocking', 42]
>>> list[-4]
'Stocking'
>>> list[-4:6]
['Stocking', 42]
>>> list[:2]以下是一个程式范例 (如果您想的话,可在诗的定义上复制及贴上):
[0, 'Fred']
>>> list[-2:]
['Jack', 'Jill']
>>> list[:3]
[0, 'Fred', 2]
>>> list[:-5]
[0, 'Fred', 2]
poem = ["<B>","Jack","and","Jill","</B>","went","up","the","hill","to","<B>",\输出结果如下:
"fetch","a","pail","of","</B>","water.","Jack","fell","<B>","down","and",\
"broke","</B>","his","crown","and","<B>","Jill","came","</B>","tumbling",\
"after"]
def get_bolds(list):
true = 1
false = 0
## is_bold tells whether or not the we are currently looking at
## a bold section of text.
is_bold = false
## start_block is the index of the start of either an unbolded
## segment of text or a bolded segment.
start_block = 0
for index in range(len(list)):
##Handle a starting of bold text
if list[index] == "<B>":
if is_bold:
print "Error: Extra Bold"
##print "Not Bold:",list[start_block:index]
is_bold = true
start_block = index+1
##Handle end of bold text
##Remember that the last number in a slice is the index
## after the last index used.
if list[index] == "</B>":
if not is_bold:
print "Error: Extra Close Bold"
print "Bold [",start_block,":",index,"] ",\
list[start_block:index]
is_bold = false
start_block = index+1
get_bolds(poem)
Bold [ 1 : 4 ] ['Jack', 'and', 'Jill']
Bold [ 11 : 15 ] ['fetch', 'a', 'pail', 'of']
Bold [ 20 : 23 ] ['down', 'and', 'broke']
Bold [ 28 : 30 ] ['Jill', 'came']
get_bold 函式会取得清单,分割为字及标记。它寻找的标记为 <B>
,会开始粗体文字,而 <\B> 会结束粗体文字。get_bold 函式会搜寻开始及结束标记。
lists 的下一项特点是复制它们,如果您尝试一些简单的东西如:
>>> a = [1,2,3]这可能会有点出人意表,因为修改 a 亦会令 b 有改变,导致
>>> b = a
>>> print b
[1, 2, 3]
>>> b[1] = 10
>>> print b
[1, 10, 3]
>>> print a
[1, 10, 3]
b = a 句式令 b
成为 a 的参照。这表示 b 可以被认为是 a 的另一个名称。结果 b 的任何改变亦会令
a 有所改变。不过有些任务却不会为一个清单建立两个名称:
>>> a = [1,2,3]
>>> b = a*2
>>> print a
[1, 2, 3]
>>> print b
[1, 2, 3, 1, 2, 3]
>>> a[1] = 10
>>> print a
[1, 10, 3]
>>> print b
[1, 2, 3, 1, 2, 3]
在这个情况下,b 不是 a 的一个参照,因为 a*2 表达式会建立一个新的 list。然后
b = a*2 句式会令 b 成为 a*2 的参照,而不是 a 的参照。 所有任务操作会建立一个参照,当您传回一个
list 成为函式的参数时,您亦建立一个参照。很多时也无须担忧有关建立参照多于复制。不过当您需要修改一个 list,而无须更改list 的另一个名称,您需要确定您实际建立了一个复本。
我们有几个方法可以建立 list 的复本,最简单的是在大部分时间下可以运作,就是 slice operator,因为即使它是整个 list 的一部分,它通常会建立一个新的list:
>>> a = [1,2,3]
>>> b = a[:]
>>> b[1] = 10
>>> print a
[1, 2, 3]
>>> print b
[1, 10, 3]
slice [:] 会建立 list 的新复本,不过它只会复制最外层的 list。当中任何 sublist 仍然是原有list的 sublist 的参照。因此如 list 中包含 lists,内层的 lists 亦要复制。您可以人手做,但 Python 已包含一个模组可以做。您可以使用 copy 模组的 deepcopy 函式:
>>> import copy首先留意 a 是阵列中的一个阵列,接着要留意当
>>> a = [[1,2,3],[4,5,6]]
>>> b = a[:]
>>> c = copy.deepcopy(a)
>>> b[0][1] = 10
>>> c[1][1] = 12
>>> print a
[[1, 10, 3], [4, 5, 6]]
>>> print b
[[1, 10, 3], [4, 5, 6]]
>>> print c
[[1, 2, 3], [4, 12, 6]]
b[0][1] = 10 执行时,
a 和 b 都会被改变,但 c 不会。这是因为当使用 slice operator 时,内层的阵列仍然是参照。不过
deepcopy c 会全面复制。
因此,我应该在每次使用函式或 = 时,担忧有关参照的问题吗?一个好消息是您只须在使用字典及 lists 时才担忧有关参照的问题。当指派数字及字串时会建立参照,但修改它们的数字上的操作会建立新的复本,因此您永不能意外地修改它们。当您在修改list或字典时,要想一想有关参照的问题。
现在您可能好奇为甚么要使用参照?基本的理由是速度,为一千个元素清单建立参照是会比复制所有元素更快。另一个原因是它允许您有函式修改输入的清单或字典,如果您曾经在不应更改的资料上,资料被修改了这些奇怪的问题,只需记着有关参照。
而现在会展示字串可以做到的出色技巧:
def shout(string):
for character in string:
print "Gimme a "+character
print "'"+character+"'"
shout("Lose")
def middle(string):
print "The middle character is:",string[len(string)/2]
middle("abcdefg")
middle("The Python Programming Language")
middle("Atlanta")
输出结果如下:
Gimme a L这些程式示范的就是字串在几种方式下与 lists 相似,shout 程序显示的 for loops 可以与字串一同使用,就像能与 lists 使用一样。中间的程序显示字串亦能使用len 函式、阵列索引及 slices,大部分 list 功能亦可以在字串上运作。
'L'
Gimme a o
'o'
Gimme a s
's'
Gimme a e
'e'
The middle character is: d
The middle character is: r
The middle character is: a
下一项功能显示一些字串特定的功能:
def to_upper(string):输出结果为:
## Converts a string to upper case
upper_case = ""
for character in string:
if 'a' <= character <= 'z':
location = ord(character) - ord('a')
new_ascii = location + ord('A')
character = chr(new_ascii)
upper_case = upper_case + character
return upper_case
print to_upper("This is Text")
THIS IS TEXT这是可以运作的,因为电脑代表字串中的字元,作为由 0 至 255 的数字。Python 有的函式称为 ord (ordinal 的缩写),会将字元传回为一个数字。此外亦有一个相应的函式称为 chr,将数字转换为字元。有了这个概代后,程式应该开始清晰。第一个详情是
if 'a' <= character <= 'z': 一行,会查看字母是否小写。假如是小写,就会使用下一行。首先它会转换至一个位置,因此
a=0,b=1,c=2 ,如此类推,还有这行:location = ord(character) - ord('a')。接着新的值以
new_ascii = location + ord('A')找到,这个值会转换为一个现在是大写的字元。
现在做一些互动的打字练习:
>>> #Integer to String
...
>>> 2
2
>>> repr(2)
'2'
>>> -123
-123
>>> repr(-123)
'-123'
>>> #String to Integer
...
>>> "23"
'23'
>>> int("23")
23
>>> "23"*2
'2323'
>>> int("23")*2
46
>>> #Float to String
...
>>> 1.23
1.23
>>> repr(1.23)
'1.23'
>>> #Float to Integer
...
>>> 1.23
1.23
>>> int(1.23)
1
>>> int(-1.23)
-1
>>> #String to Float
...
>>> float("1.23")
1.23
>>> "1.23"
'1.23'
>>> float("123")
123.0
如果您未估计,repr 函式会将整数转换为字串,而 int 函式可以将字串转换为整数。
float 函式可以将整数转换为浮点数。repr 函式传回一个可列印的展示。以下是其中一些范例:
>>> repr(1)
'1'
>>> repr(234.14)
'234.14'
>>> repr([4,42,10])
'[4, 42, 10]'
int 函式尝试将字串 (或浮点数) 转换为整数,此外亦有类似的函式称为 float ,将整数或字串转换为浮点数。Python
有的另一个函式是 eval 函式,eval 函式会得出一个字串,并传回 python 认为它找到的资料类型。例如:
>>> v=eval('123')
>>> print v,type(v)
123 <type 'int'>
>>> v=eval('645.123')
>>> print v,type(v)
645.123 <type 'float'>
>>> v=eval('[1,2,3]')
>>> print v,type(v)
[1, 2, 3] <type 'list'>
如果您使用 eval 函式,您应该查看它是否传回您预期的类型。
一个有用的字串函式是 split 函式,范例如下:
>>> import string留意
>>> string.split("This is a bunch of words")
['This', 'is', 'a', 'bunch', 'of', 'words']
>>> string.split("First batch, second batch, third, fourth",",")
['First batch', ' second batch', ' third', ' fourth']
split 如何将字串转换为一列字串,字串预设由空间分割,或可选的第二个参数 (在本例中为逗号)。
#This program requires a excellent understanding of decimal numbers
def to_string(in_int):
"Converts an integer to a string"
out_str = ""
prefix = ""
if in_int < 0:
prefix = "-"
in_int = -in_int
while in_int / 10 != 0:
out_str = chr(ord('0')+in_int % 10) + out_str
in_int = in_int / 10
out_str = chr(ord('0')+in_int % 10) + out_str
return prefix + out_str
def to_int(in_str):
"Converts a string to an integer"
out_num = 0
if in_str[0] == "-":
multiplier = -1
in_str = in_str[1:]
else:
multiplier = 1
for x in range(0,len(in_str)):
out_num = out_num * 10 + ord(in_str[x]) - ord('0')
return out_num * multiplier
print to_string(2)
print to_string(23445)
print to_string(-23445)
print to_int("14234")
print to_int("12345")
print to_int("-3512")
输出结果如下:
2
23445
-23445
14234
12345
-3512
\n 会告诉 Python
开新一行。
档案 IO 的概念是:
open 函式取得一个档案物件。 第一个步骤是取得一个档案物件,所做的方法是使用 open 函式,格式为 file_object = open(filename,mode)
,而 file_object 是储存档案物件的变数,filename 是一个字串,有档案名称,而模式
"r" 是读取档案或 "w" 写入档案。接着可以呼叫档案物件函式。两个最普遍的函式是读取及写入,
write 函式新增字串在档案的最后,read 函式读取档案下一项东西,并将它传回为字串。如果没有给予参数,它会传回整个档案
(就如范例中所完成的)。
现在以下是我们之前制作的电话号码程式的新版本:
import string true = 1 false = 0 def print_numbers(numbers): print "Telephone Numbers:" for x in numbers.keys(): print "Name: ",x," \tNumber: ",numbers[x] print def add_number(numbers,name,number): numbers[name] = number def lookup_number(numbers,name): if numbers.has_key(name): return "The number is "+numbers[name] else: return name+" was not found" def remove_number(numbers,name): if numbers.has_key(name): del numbers[name] else: print name," was not found" def load_numbers(numbers,filename): in_file = open(filename,"r") while true: in_line = in_file.readline() if in_line == "": break in_line = in_line[:-1] [name,number] = string.split(in_line,",") numbers[name] = number in_file.close() def save_numbers(numbers,filename): out_file = open(filename,"w") for x in numbers.keys(): out_file.write(x+","+numbers[x]+"\n") out_file.close() def print_menu(): print '1. Print Phone Numbers' print '2. Add a Phone Number' print '3. Remove a Phone Number' print '4. Lookup a Phone Number' print '5. Load numbers' print '6. Save numbers' print '7. Quit' print phone_list = {} menu_choice = 0 print_menu() while menu_choice != 7: menu_choice = input("Type in a number (1-7):") if menu_choice == 1: print_numbers(phone_list) elif menu_choice == 2: print "Add Name and Number" name = raw_input("Name:") phone = raw_input("Number:") add_number(phone_list,name,phone) elif menu_choice == 3: print "Remove Name and Number" name = raw_input("Name:") remove_number(phone_list,name) elif menu_choice == 4: print "Lookup Number" name = raw_input("Name:") print lookup_number(phone_list,name) elif menu_choice == 5: filename = raw_input("Filename to load:") load_numbers(phone_list,filename) elif menu_choice == 6: filename = raw_input("Filename to save:") save_numbers(phone_list,filename) elif menu_choice == 7: pass else: print_menu() print "Goodbye" Notice that it now includes saving and loading files. Here is some output of my running it twice: > python tele2.py 1. Print Phone Numbers 2. Add a Phone Number 3. Remove a Phone Number 4. Lookup a Phone Number 5. Load numbers 6. Save numbers 7. Quit Type in a number (1-7):2 Add Name and Number Name:Jill Number:1234 Type in a number (1-7):2 Add Name and Number Name:Fred Number:4321 Type in a number (1-7):1 Telephone Numbers: Name: Jill Number: 1234 Name: Fred Number: 4321 Type in a number (1-7):6 Filename to save:numbers.txt Type in a number (1-7):7 Goodbye > python tele2.py 1. Print Phone Numbers 2. Add a Phone Number 3. Remove a Phone Number 4. Lookup a Phone Number 5. Load numbers 6. Save numbers 7. Quit Type in a number (1-7):5 Filename to load:numbers.txt Type in a number (1-7):1 Telephone Numbers: Name: Jill Number: 1234 Name: Fred Number: 4321 Type in a number (1-7):7 Goodbye这个程式的新部分是:
def load_numbers(numbers,filename): in_file = open(filename,"r") while 1: in_line = in_file.readline() if len(in_line) == 0: break in_line = in_line[:-1] [name,number] = string.split(in_line,",") numbers[name] = number in_file.close() def save_numbers(numbers,filename): out_file = open(filename,"w") for x in numbers.keys(): out_file.write(x+","+numbers[x]+"\n") out_file.close()首先我们会查看程式的 save 部分,它先以 open(filename, "w") 指令建立一个档案物件,接着它会以 out_file.write(x+","+numbers[x]+"\n")
指令为每个电话号码经过并建立一行,这会写入一行,包含名称、一个逗号、数字及新一行。
载入的部分有点复杂,它会透过取得一个档案物件开始,然后它会使用 while 1: loop 保持 looping
,直至遇到 break 句式,接着它会得出 in_line = in_file.readline()一行,当遇到档案结尾时,
readline 函式会传回一个空白的字串 (len(string) == 0)。if
句式会查看这个,而当这种情况发生时,会中断 while loop。当然,如果 readline
函式未在该行结尾传回新一行,没有方式辨别空白字串是空白行或档案的结尾,因此在传回 readline 时会保留新一行。因此我们要取消新一行,
in_line = in_line[:-1] 一行会透过放弃最后一个字元为我们做到,接着一行 [name,number]
= string.split(in_line,",") 会在逗号分割该行为一个名称及一个数字,然后会加入数字字典。
现在修改第 11 部分的分数程式,令它使用档案 IO 保留学生的记录。
因此您现在有完整的程式,它会完美无误地执行,除非有一项事情会令它在无效的使用者输入时崩溃。不用害怕,因为 Python 有特别的控制结构,称为
try,并会尝试做一些事情。以下是有问题的程式范例:
留意当您输入 @#& 时,它如何输出一些东西:
您看到 int 函式不太高兴 @#& 数字 (它应该是),最后一行会显示问题所在;Python
找到一个 ValueError,我们的程式会如何处理?我们首先要做的是:将错误出现的地方放在 try
block 内,第二:告诉 Python 我们想 ValueError s 如何处理,以下的程式会做到:
现在当我们执行新程式时,会得出 @#& ,它会告诉我们 ``That was not a number.''
并继续它之前所做的。
当程式仍然有一些错误时,您会知道如何处理,将源码放在 try block,并在 except block 处理错误。
至少将电话号码程式更新,因此如果使用者不在选单输入任何资料,它不会崩溃。
本教学正在改进中,欢迎对其功能提出任何意见。感谢您的电邮,令我完成大量工作,作出改善及更聆聪意见 :)。
祝您编程愉快,希望它可以改变您的生命及世界。
TODO=[ 'errors','how to make modules','more on loops','more on strings', 'file io','how to use online help','try','pickle','anything anyone suggests that I think is a good idea']
>>>
在首的模式。) 本文件使用 LaTeX 2HTML translator Version 2K.1beta (1.48) 产生。
Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer
Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department,
Macquarie University, Sydney.
指令行参数是:
latex2html -split 3 -local_icons -address 'Josh
Cogliati jjc@honors.montana.edu
' easytut.tex
翻译由 Josh Cogliati 在 2003-03-17 开始。