分享

Python基础笔记-02

gefieder 发表于 2015-4-25 22:39:50 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 14599
本帖最后由 gefieder 于 2015-4-25 22:41 编辑
问题导读:
1、什么是函数?什么是迭代?
2、如何编写函数?
3、如何切片?




接上篇: Python基础笔记-01

五、函数
5.1、什么是函数
函数就是最基本的一种代码抽象的方式。
5.2、调用函数
要调用一个函数,需要知道函数的名称和参数
5.3、编写函数
定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。
  1. def my_abs(x):
  2.     if x >= 0:
  3.         return x
  4.     else:
  5.         return -x
复制代码
5.4、返回多值
  1. import math
  2. def move(x, y, step, angle):
  3.     nx = x + step * math.cos(angle)
  4.     ny = y - step * math.sin(angle)
  5.     return nx, ny
  6. >>> x, y = move(100, 100, 60, math.pi / 6)
  7. >>> print x, y
  8. 151.961524227 70.0
  9. # 其实这只是一种假象,Python函数返回的仍然是单一值:
  10. >>> r = move(100, 100, 60, math.pi / 6)
  11. >>> print r
  12. (151.96152422706632, 70.0)
复制代码
5.5、递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * … * n,用函数 fact(n)表示,
  1. fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n
复制代码
于是,fact(n)用递归的方式写出来就是:
  1. def fact(n):
  2.     if n==1:
  3.         return 1
  4.     return n * fact(n - 1)
  5. >>> fact(1)
  6. 1
  7. >>> fact(5)
  8. 120
复制代码
如果我们计算fact(5),可以根据函数定义看到计算过程如下:
  1. ===> fact(5)
  2. ===> 5 * fact(4)
  3. ===> 5 * (4 * fact(3))
  4. ===> 5 * (4 * (3 * fact(2)))
  5. ===> 5 * (4 * (3 * (2 * fact(1))))
  6. ===> 5 * (4 * (3 * (2 * 1)))
  7. ===> 5 * (4 * (3 * 2))
  8. ===> 5 * (4 * 6)
  9. ===> 5 * 24
  10. ===> 120
复制代码
汉诺塔 的移动也可以看做是递归函数。
我们对柱子编号为a, b, c,将所有圆盘从a移到c可以描述为:
- 如果a只有一个圆盘,可以直接移动到c;
- 如果a有N个圆盘,可以看成a有1个圆盘(底盘) + (N-1)个圆盘,首先需要把 (N-1) 个圆盘移动到 b,然后,将 a的最后一个圆盘移动到c,再将b的(N-1)个圆盘移动到c。
请编写一个函数,给定输入 n, a, b, c,打印出移动的步骤:
move(n, a, b, c)
例如,输入 move(2, ‘A’, ‘B’, ‘C’),打印出:
A –> B
A –> C
B –> C
  1. def move(n, a, b, c):
  2.     if n ==1:
  3.         print a, '-->', c
  4.         return
  5.     move(n-1, a, c, b)
  6.     move(1, a, b, c) # 或 print a, '-->', c
  7.     move(n-1, b, a, c)
  8. move(4, 'A', 'B', 'C')
复制代码
5.6、定义默认参数
函数的默认参数的作用是简化调用
  1. def power(x, n=2):
  2.     s = 1
  3.     while n > 0:
  4.         n = n - 1
  5.         s = s * x
  6.     return s
  7. >>> power(5)
  8. 25
复制代码
默认参数只能定义在必需参数的后面:
  1. # OK:
  2. def fn1(a, b=1, c=2):
  3.     pass
  4. # Error:
  5. def fn2(a=1, b):
  6.     pass
复制代码
5.7、定义可变参数
如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数:
  1. def fn(*args):
  2.     print args
  3. #在函数内部,直接把变量 args 看成一个 tuple 就好了
复制代码
六、切片
6.1、对list进行切片
取一个list的部分元素是非常常见的操作:
  1. >>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
复制代码
取前3个元素,用一行代码就可以完成切片:
  1. >>> L[0:3]
  2. ['Adam', 'Lisa', 'Bart']
复制代码
L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
如果第一个索引是0,还可以省略:
  1. >>> L[:3]
  2. ['Adam', 'Lisa', 'Bart']
复制代码
只用一个 : ,表示从头到尾:
  1. >>> L[:]
  2. ['Adam', 'Lisa', 'Bart', 'Paul']
复制代码
切片操作还可以指定第三个参数:
  1. >>> L[::2]
  2. ['Adam', 'Bart']
复制代码
第三个参数表示每N个取一个,上面的 L[::2] 会每两个元素取出一个来,也就是隔一个取一个。
把list换成tuple,切片操作完全相同,只是切片的结果也变成了tuple。
6.2、倒序切片
  1. >>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
  2. >>> L[-2:]
  3. ['Bart', 'Paul']
  4. >>> L[:-2]
  5. ['Adam', 'Lisa']
  6. >>> L[-3:-1]
  7. ['Lisa', 'Bart']
  8. >>> L[-4:-1:2]
  9. ['Adam', 'Bart']
复制代码
记住倒数第一个元素的索引是-1。倒序切片包含起始索引,不包含结束索引。
6.3、对字符串切片
字符串 ‘xxx’和 Unicode字符串 u’xxx’也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串:
  1. >>> 'ABCDEFG'[:3]
  2. 'ABC'
  3. >>> 'ABCDEFG'[-3:]
  4. 'EFG'
  5. >>> 'ABCDEFG'[::2]
  6. 'ACEG'
复制代码
七、迭代
7.1、什么是迭代
在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Iteration)。
Python 的 for循环不仅可以用在list或tuple上,还可以作用在其他任何可迭代对象上。
注意: 集合是指包含一组元素的数据结构,我们已经介绍的包括:
1. 有序集合:list,tuple,str和unicode;
2. 无序集合:set
3. 无序集合并且具有 key-value 对:dict
7.2、索引迭代
Python中,迭代永远是取出元素本身,而非元素的索引。
有的时候,我们确实想在 for 循环中拿到索引,怎么办?
方法是使用 enumerate() 函数:
  1. >>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
  2. >>> for index, name in enumerate(L):
  3. ...     print index, '-', name
  4. ...
  5. 0 - Adam
  6. 1 - Lisa
  7. 2 - Bart
  8. 3 - Paul
复制代码
7.3、迭代dict的value
dict 对象有一个 values() 方法,这个方法把dict转换成一个包含所有value的list,我们迭代的就是 dict的每一个 value:
  1. d= { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
  2. print d.values()
  3. # [85, 95, 59]
  4. for v in d.values():
  5.     print v
  6. # 85
  7. # 95
  8. # 59
复制代码
dict除了values()方法外,还有一个 itervalues() 方法,用 itervalues() 方法替代 values() 方法,迭代效果完全一样:
  1. d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
  2. print d.itervalues()
  3. # <dictionary-valueiterator object at 0x106adbb50>
  4. for v in d.itervalues():
  5.     print v
  6. # 85
  7. # 95
  8. # 59
复制代码
1. values() 方法实际上把一个 dict 转换成了包含 value 的list。
2. itervalues() 方法不会转换,它会在迭代过程中依次从 dict 中取出 value,所以 itervalues() 方法比 values() 方法节省了生成 list 所需的内存。
7.4、迭代dict的key和value
dict 对象的 items() 方法返回的值:
  1. >>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
  2. >>> print d.items()
  3. [('Lisa', 85), ('Adam', 95), ('Bart', 59)]
复制代码
items() 方法把dict对象转换成了包含tuple的list,我们对这个list进行迭代,可以同时获得key和value:
  1. >>> for key, value in d.items():
  2. ...     print key, ':', value
  3. ...
  4. Lisa : 85
  5. Adam : 95
  6. Bart : 59
复制代码
和 values() 有一个 itervalues() 类似, items() 也有一个对应的 iteritems(),iteritems() 不把dict转换成list,而是在迭代过程中不断给出 tuple,所以, iteritems() 不占用额外的内存。
八、列表生成式
8.1、生成列表
要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我们可以用range(1, 11):
  1. >>> range(1, 11)
  2. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
复制代码
但如果要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?方法一是循环:
  1. >>> L = []
  2. >>> for x in range(1, 11):
  3. ...    L.append(x * x)
  4. ...
  5. >>> L
  6. [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
复制代码
但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:
  1. >>> [x * x for x in range(1, 11)]
  2. [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
复制代码
8.2、复杂表达式
  1. d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
  2. tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()]
  3. print '<table>'
  4. print '<tr><th>Name</th><th>Score</th><tr>'
  5. print '\n'.join(tds)
  6. print '</table>'
复制代码
'注:字符串可以通过 % 进行格式化,用指定的参数替代 %s。字符串的join()方法可以把一个 list 拼接成一个字符串。
8.3、条件过滤
列表生成式的 for 循环后面还可以加上 if 判断。例如:
  1. >>> [x * x for x in range(1, 11)]
  2. [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
复制代码
如果我们只想要偶数的平方,不改动 range()的情况下,可以加上 if 来筛选:
  1. >>> [x * x for x in range(1, 11) if x % 2 == 0]
  2. [4, 16, 36, 64, 100]
复制代码
8.4、多层表达式
for循环可以嵌套,因此,在列表生成式中,也可以用多层 for 循环来生成列表。
对于字符串 ‘ABC’ 和 ‘123’,可以使用两层循环,生成全排列:
  1. >>> [m + n for m in 'ABC' for n in '123']
  2. ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
复制代码
利用 3 层for循环的列表生成式,找出对称的 3 位数。例如,121 就是对称数,因为从右到左倒过来还是 121。
  1. print [100 * n1 + 10 * n2 + n3 for n1 in range(1, 10) for n2 in range(10) for n3 in range(10) if n1==n3]
复制代码
本笔记基于慕课网的Python基础教程加上部分个人总结编写而成
资料来源:http://blog.csdn.net/ys743276112/article/details/45203753

欢迎加入about云群371358502、39327136,云计算爱好者群,亦可关注about云腾讯认证空间||关注本站微信

已有(1)人评论

跳转到指定楼层
Riace12 发表于 2015-4-26 16:40:05
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条