五、List类型
列表(list)是Python内置的一种数据类型。list是一种有序的集合,可以随时添加和删除其中的元素。
由于Python是动态语言,所以list中包含的元素可以是不同数据类型,也可以为空。
1、创建List:classmates = ['Michael', 'Bob', 'Tracy']
L = ['Michael', 100, True]
空list:empty_list = []
2、按索引访问List:索引从 0 开始,第一个元素的索引是0,第二个元素的索引是1,以此类推。
要打印第一个同学的名字,用 classmates [0]。
使用索引时,千万注意不要越界。当输入classmates [3]会报错。
3、倒序访问List:用 -1 这个索引来表示最后一个元素。类似的,倒数第二用 -2 表示,倒数第三用 -3 表示。
使用倒序索引时,也要注意不要越界。
4、增加新元素 例: L = ['Adam', 'Lisa', 'Bart']
1)用 list 的 append() 方法,追加到 list 的末尾: L.append('Paul')
2)用list的 insert()方法,它接受两个参数,第一个参数是索引号,第二个参数是待添加的新元素。插入后原来的元素都自动向后移一位:L.insert(0, 'Paul')
5、从List删除元素
1)可以用list的pop()方法删除,pop()方法总是删掉list的最后一个元素,并且它还返回这个元素(在命令提示符窗口中显示):L.pop()
2)pop(索引): L.pop(2)
6、替换元素:对list中的某一个索引赋值,就可以直接用新的元素替换掉原来的元素,list包含的元素个数保持不变。
L[2] = 'Paul'
六、Tuple类型
tuple,又称“ 元组 ”。tuple 和 list 非常类似,是另一种有序的列表,但一旦创建完毕,就不能修改。
1、创建tuple:和创建list唯一不同之处是用( )
替代了[ ]
: t = ('Adam', 'Lisa', 'Bart')
获取 tuple 元素的方式和 list 是一样的,使用 t[0],t[-1]等索引方式访问元素。
2、创建单元素tuple:空tuple:t = ()
单元素 tuple 要多加一个逗号“,”,这样就避免了歧义: t = (1,) 。在打印单元素tuple时,也自动添加了一个“,”。
3、可变的tuple:tuple中包含列表[list]
t = ('a', 'b', ['A', 'B'])
tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
七、条件判断和循环
1、if语句
1)Python中具有相同缩进的代码被视为代码块。缩进是4个空格,不要使用Tab。
2) if 语句后接表达式,然后用:
表示代码块开始。
3)在Python交互环境下敲代码,还要特别留意缩进,并且退出缩进需要多敲一行回车。
age = 20 if age >= 18: print 'your age is', age print 'adult' print 'END'
2、if-else:利用 if ... else ... 语句,我们可以根据条件表达式的值为 True 或者 False ,分别执行 if 代码块或者 else 代码块。
if age >= 18: print 'adult' else: print 'teenager'
注意: else 后面有个“:”。
3、if-elif-else:这一系列条件判断会从上到下依次判断,如果某个判断为 True,执行完对应的代码块,后面的条件判断就直接忽略,不再执行了。
故在自己编写代码时,条件也是从大到小划分。
if age >= 18:
print 'adult' elif age >= 6: print 'teenager' elif age >= 3: print 'kid' else: print 'baby'
4、for循环: for 循环遍历一个list或tuple:
L = ['Adam', 'Lisa', 'Bart'] for name in L: print name
注意: name 这个变量是在 for 循环中定义的,意思是,依次取出list中的每一个元素,并把元素赋值给 name,然后执行for循环体(就是缩进的代码块)。
5、while循环:while 循环不会迭代 list 或 tuple 的元素,而是根据表达式判断循环是否结束。
比如要从 0 开始打印不大于 N 的整数:
N = 10 x = 0 while x < N: print x x = x + 1
while循环每次先判断 x < N,如果为True,则执行循环体的代码块,否则,退出循环。
6、break退出循环:用 for 循环或者 while 循环时,如果要在循环体内直接退出循环,可以使用 break 语句。
利用 while True 无限循环配合 break 语句,计算 1 + 2 + 4 + 8 + 16 + ... 的前20项的和:
sum = 0
x = 1
n = 1
while True:
sum=sum+x
x=2*x
n=n+1
if n>20:
break
print sum
7、continue继续循环:用continue跳过后续循环代码,继续下一次循环。
假设我们已经写好了利用for循环计算平均分的代码:
L = [75, 98, 59, 81, 66, 43, 69, 85] sum = 0.0 n = 0 for x in L: sum = sum + x n = n + 1 print sum / n
现在老师只想统计及格分数的平均分,就要把 x < 60 的分数剔除掉,这时,利用 continue,可以做到当 x < 60的时候,不继续执行循环体的后续代码,直接进入下一次循环:
for x in L: if x < 60: continue sum = sum + x n = n + 1
8、多重循环:在循环内部嵌套循环。
对100以内的两位数,请使用一个两重循环打印出所有十位数数字比个位数数字小的数,例如,23(2 < 3)
for x in ['1','2','3','4','5','6','7','8','9']:
for y in ['0','1','2','3','4','5','6','7','8','9']:
if x<y:
print x+y
八、dict和set类型
1、什么是dict:
1)dict是用一对花括号{}表示的,然后按照 key: value, 写出来,最后一个 key: value 的逗号可以省略。
2)通过 key 来查找 value。
3)list 和 tuple 可以用来表示顺序集合,而dict是无序列表。
4)dict也是集合,len() 函数可以计算任意集合的大小:len(d)
用 dict 表示“名字”-“成绩”的查找表如下:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print 'Adam:',d['Adam'] #输出用,相连。
2、访问dict:使用 d[key] 的形式来查找对应的 value。
1)和 list 类似,不同之处是,list 必须使用索引返回对应的元素,而dict使用key。
2)如果key不存在,会直接报错:KeyError。
3)为避免 KeyError 发生,有两个办法:
一是先判断一下 key 是否存在,用 in 操作符:if 'Paul' in d:
print d['Paul']
二是使用dict本身提供的一个 get 方法,在Key不存在的时候,返回None: >>> print d.get('Bart')
59 >>> print d.get('Paul') None
3、 dic的特点
1)查找速度快,而list的查找速度随着元素增加而逐渐下降。缺点是占用内存大,还会浪费很多内容。
2)在一个dict中,key不能重复。
3)存储的key-value序对是没有顺序的。打印的顺序不一定是我们创建时的顺序。
4)作为 key 的元素必须不可变,Python的基本类型如字符串、整数、浮点数都是不可变的,都可以作为 key。但是list是可变的,就不能作为 key。
不可变这个限制仅作用于key,value是否可变无所谓:
{ '123': [1, 2, 3], # key 是 str,value是list 123: '123', # key 是 int,value 是 str ('a', 'b'): True # key 是 tuple,并且tuple的每个元素都是不可变对象,value是 boolean }
4、更新dict
1)增加,用赋值语句:d['Paul'] = 72。
2)替换,用赋值语句,如果 key 已经存在,则赋值会用新的 value 替换掉原来的 value。
5、遍历dict:类似于list,都可以通过 for 循环实现。
请用 for 循环遍历如下的dict,打印出 name: score 来。
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
for key in d:
print key,':',d[key]
6、什么是set:set 持有一系列元素,这一点和 list 很像,但是set的元素没有重复,而且是无序的,这点和 dict 的 key很像。
相当于我们只想要 dict 的 key,不关心 key 对应的 value,目的就是保证这个集合的元素不会重复。
创建 set 的方式是调用 set() 并传入一个 list,list的元素将作为set的元素:
s = set(['A', 'B', 'C'])
可以查看 set 的内容:
print s set(['A', 'C', 'B'])
当我们传入包含重复元素的 list ,set会自动去掉重复的元素。
7、访问set
1)因为是无序的,所以不能通过索引来访问。
2)用 in 操作符判断,大小写很重要。
s = set(['Adam', 'Lisa', 'Bart', 'Paul'])
'Bart' in s True
8、 set的特点
1)判断一个元素是否在set中速度很快。
2)任何可变对象是不能放入set中的。
3)set存储的元素也是没有顺序的。
4)应用:星期:事先创建好一个set,包含'MON' ~ 'SUN':
weekdays = set(['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'])
再判断输入是否有效,只需要判断该字符串是否在set中:
x = '???' # 用户输入的字符串 if x in weekdays: print 'input ok' else: print 'input error'
9、遍历set
set 也是一个集合,所以,遍历 set 和遍历 list 类似,都可以通过 for 循环实现。
>>> s = set(['Adam', 'Lisa', 'Bart']) >>> for name in s: ... print name
注意: for 循环在遍历set时,元素的顺序和list的顺序很可能是不同的,而且不同的机器上运行的结果也可能不同。
例:请用 for 循环遍历如下的set,打印出 name: score 来
s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])
for x in s:
print x[0],':',x[1]
10、更新set:主要做两件事:
一是把新的元素添加到set中,二是把已有元素从set中删除。
1)添加元素时,用set的add()方法,如果添加的元素已经存在于set中,add()不会报错,但是不会加进去了:
>>> s = set([1, 2, 3]) >>> s.add(4) >>> print s set([1, 2, 3, 4])
2)删除set中的元素时,用set的remove()方法,如果删除的元素不存在set中,remove()会报错:
>>> s = set([1, 2, 3, 4]) >>> s.remove(4) >>> print s set([1, 2, 3])
所以用add()可以直接添加,而remove()前需要判断。
九、函数
1、关于函数
1)函数可以只写一次,然后多次调用。
2)函数就是最基本的一种代码抽象的方式,如数学中计算数列1-100的和记作:
100 ∑n n=1
2、调用函数
Python内置了很多有用的函数,我们可以直接调用。
要调用一个函数,需要知道函数的名称和参数。
例:求绝对值的函数 abs,它接收一个参数:abs(-20)。
调用函数的时候,如果传入的参数数量不对,会报TypeError的错误。
如果传入的参数数量是对的,但参数类型不能被函数所接受,也会报TypeError的错误,并且给出错误信息。
例:比较函数 cmp(x, y) 就需要两个参数,如果 x<y,返回 -1,如果 x==y,返回 0,如果 x>y,返回 1:
>>> cmp(1, 2) -1 >>> cmp(2, 1) 1 >>> cmp(3, 3) 0
例:数据类型转换函数,比如 int()函数可以把其他数据类型转换为整数:
>>> int('123') 123 >>> int(12.34) 12
例:str()函数把其他类型转换成 str:
>>> str(1.23) '1.23'
3、编写函数
定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。
请定义一个 square_of_sum 函数,它接受一个list,返回list中每个元素平方的和。
def square_of_sum(L):
sum=0
for x in L:
sum=sum+x*x
return sum
print square_of_sum([1, 2, 3, 4, 5])
print square_of_sum([-5, 0, 5, 15, 25])
请注意,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。
如果没有return语句,函数执行完毕后也会返回结果,只是结果为 None。return None可以简写为return。
4、返回多值——其实就是返回一个tuple
比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的坐标:
# math包提供了sin()和 cos()函数,我们先用import引用它:
import math def move(x, y, step, angle): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx, ny
这样我们就可以同时获得返回值:
>>> x, y = move(100, 100, 60, math.pi / 6) >>> print x, y 151.961524227 70.0
但其实这只是一种假象,Python函数返回的仍然是单一值:
>>> r = move(100, 100, 60, math.pi / 6) >>> print r (151.96152422706632, 70.0)
用print打印返回结果,原来返回值是一个tuple!
但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple。
例:一元二次方程的定义是:ax² + bx + c = 0,请编写一个函数,返回一元二次方程的两个解。
注意:Python的math包提供了sqrt()函数用于计算平方根。
import math
def quadratic_equation(a, b, c):
x1=(-b+math.sqrt(b*b-4*a*c))/(2*a)
x2=(-b-math.sqrt(b*b-4*a*c))/(2*a)
return x1,x2
print quadratic_equation(2, 3, 0)
print quadratic_equation(1, -6, 5)
5、递归函数——如果一个函数在内部调用自身本身,这个函数就是递归函数。
举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n,用函数 fact(n)表示,可以看出:
fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n
所以,fact(n)可以表示为 n * fact(n-1),只有n=1时需要特殊处理。
于是,fact(n)用递归的方式写出来就是:
def fact(n): if n==1: return 1 return n * fact(n - 1)
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试计算 fact(10000)。