计算机科学和Python编程导论week3

递归
In [1]: def factl(n):
   ...:     res = 1
   ...:     while n > 1:
   ...:         res = res * n 
   ...:         n -= 1
   ...:     return res
   ...: 

# 写成递归函数
In [2]: def factR(n):
   ...:     if n == 1:
   ...:         return n
   ...:     return n*factR(n-1)
   ...: 

In [3]: factl(5)
Out[3]: 120

In [4]: factR(5)
Out[4]: 120

In [5]: factl(10)
Out[5]: 3628800

In [6]: factR(10)
Out[6]: 3628800

# 汉诺塔
In [7]: def printMove(fr, to):
   ...:     print('move from ' + str(fr) + ' to ' + str(to))
   ...: 
   ...: def Towers(n, fr, to, spare):
   ...:     if n == 1:
   ...:         printMove(fr, to)
   ...:     else:
   ...:         Towers(n-1, fr, spare, to)
   ...:         Towers(1, fr, to, spare)
   ...:         Towers(n-1, spare, to, fr)

元组、字符串、列表、字典练习

元组

元组用圆括号标记。组中只包含一个元素时,需要在元素后面添加逗号。元组的一个特性是没有重复的元素。其他特性如下:

>>> tup1 = ()
>>> tup1
()
>>> tup1 = (12,)
>>> tup1
(12,)

# 元组和字符串类似,可以通过下标来进行索引和切片
>>> tup1 = ('physics', 'chemistry', 1997, 2000)
>>> tup2 = (1, 2, 3, 4, 5, 6, 7 )
>>> tup1[2]
1997
>>> tup1[1:3]
('chemistry', 1997)

# 元组中的元素不允许修改,但是可以进行连接组合以及删除整个元组
>>> tup3 = (12,34,'abc','xyz')
>>> tup3[0] = 33
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> tup4 = (56,33)
# 可以用+号来进行连接
>>> tup5 = tup3+tup4
>>> tup5
(12, 34, 'abc', 'xyz', 56, 33)
# 元组删除后,再打印会进行报错
>>> del tup5
>>> tup5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'tup5' is not defined


#元组的一些内置函数如下:
len(tuple)
计算元组元素个数。
max(tuple)
返回元组中元素最大值。
min(tuple)
返回元组中元素最小值。 

字符串

在python中字符串是最常见的类型,可以用单引号或双引号来创建。

# 可以对字符串进行索引和切片
#需要在字符中使用特殊字符时,python用反斜杠(\)转义字符。
>>> str1 = 'hellopython'
>>> str1[1]
'e'
>>> str1[2:5]
'llo'
>>> str1[5:] = 'timekiller'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> str1[:5] + 'timekiller'
'hellotimekiller'

# 字符串还可以进行运算等
>>> a = 'hello'
>>> b = 'timekiller'
>>> a + b 
'hellotimekiller'
>>> a * 2
'hellohello'
列表

列表中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。

>>> list1 = ['my','python',12, 23]
>>> list1[0]
'my'
>>> list1[2]
12
>>> list1[1:3]
['python', 12]

# 使用append来添加元素,只能单个追加
>>> list = []
>>> list.append('Google')
>>> list.append('Tecent')
>>> list
['Google', 'Tecent']

# 还可以进行删除列表元素
>>> del list[1]
>>> list
['Google']

# 列表的一些其他操作
>>> len([1,2,3])
3
>>> [1,2,3]+[4,5,6]
[1, 2, 3, 4, 5, 6]
>>> ['Hi'] * 4
['Hi', 'Hi', 'Hi', 'Hi']
>>> 3 in [1,2,3]
True
>>> for x in [1,2,3]:
...     print (x)
... 
1
2
3

其他一些列表中的方法如下:

方法 说明
list.append(obj) 在列表末尾添加新的对象
list.count(obj) 统计某个元素在列表中出现的次数
list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
list.insert(index, obj) 将对象插入列表
list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
list.remove(obj) 移除列表中某个值的第一个匹配项
list.reverse() 反向列表中元素
list.sort(cmp=None, key=None, reverse=False) 对原列表进行排序
字典

字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中。

>>> dict = {'alice':1992,'bob':1989,'beth':1995}
>>> dict
{'alice': 1992, 'bob': 1989, 'beth': 1995}
>>> type(dict)
<class 'dict'>

# 通过键来访问字典中的元素
>>> dict['alice']
1992
# 通过增加键值对增加字典中的元素
>>> dict['dylan']=1997
>>> dict
{'alice': 1992, 'bob': 1989, 'beth': 1995, 'dylan': 1997}
# 通过键删除字典中的元素
>>> del dict['bob']
>>> dict
{'alice': 1992, 'beth': 1995, 'dylan': 1997}
# 创建时如果同一个键被赋值两次,后一个值会被记住
>>> dict1 = {'name':'zara','age':7,'name':'manni'}
>>> dict1
{'name': 'manni', 'age': 7}

其他需要记住的是:键不允许出现两次,键值必须不可变。

生成器和迭代器

1、生成器。

在Python中,这种一边循环一边计算的机制,称为生成器:generator。要创建一个generator,可以通过把一个列表生成式的[]改成(),就创建了一个generator:

In [1]: L = [x * x for x in range(10)]
In [2]: L
Out[2]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [5]: g = (x * x for x in range(10))
In [6]: g
Out[6]: <generator object <genexpr> at 0x000000001137A7D8>

In [7]: next(g)
Out[7]: 0
In [8]: next(g)
Out[8]: 1

# 可以通过for循环来进行调用
In [9]: for n in g:
   ...:     print(n)
   ...:     
4
9
16
25
36
49
64
81

要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。

# 请注意区分普通函数和generator函数,普通函数调用直接返回结果:
In [10]: f = abs(-6)

In [11]: f
Out[11]: 6

# generator函数的“调用”实际返回一个generator对象:
In [13]: def fib(max):
    ...:     n, a, b = 0, 0, 1
    ...:     while n < max:
    ...:         yield b
    ...:         a, b = b, a + b
    ...:         n = n + 1
    ...:     return 'done'
    ...: 
In [14]: g =fib(6)
In [15]: g
Out[15]: <generator object fib at 0x0000000011139D58>
2、迭代器

直接作用于for循环的对象统称为可迭代对象:Iterable,一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和带yield的generator function。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator,它们表示一个惰性计算的序列。

# 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
In [16]: it = iter([1,2,3,4,5])

In [17]: it
Out[17]: <list_iterator at 0x113a7710>

In [18]: next(it)
Out[18]: 1

3、列表生成式
In [19]: [x * x for x in range(1,11)]
Out[19]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

In [21]: [x * x for x in range(1,11) if x % 2 == 0]
Out[21]: [4, 16, 36, 64, 100]

In [22]: L = ['Hello','World','IBM','Apple']

In [23]: [s.lower() for s in L]
Out[23]: ['hello', 'world', 'ibm', 'apple']

map、reduce、filter、sorted 以及匿名函数

map的功能:map(f, [x1,x2,x3]) = [f(x1), f(x2), f(x3)],3.x的版本返回的是个迭代器
In [24]: def f(x):
    ...:     return x*x
    ...: 
In [25]: a = map(f,[1,2,3,4,5])

In [26]: a
Out[26]: <map at 0x113a6978>

In [28]: for x in a:
    ...:     print (x)
    ...:     
1
4
9
16
25

reduce()的用法:reduce(f, [x1, x2, x3]) = f(f(f(x1,x2),x3),x4).
#在 Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 fucntools 模块里,
#如果想要使用它,则需要通过引入 functools 模块来调用 reduce() 函数:
In [29]: def add(x,y):
    ...:     return x+y
    ...: print(reduce(add,[1,2,3,4,5]))
    ...: 
Traceback (most recent call last):

  File "<ipython-input-29-9ad4364ab3ea>", line 3, in <module>
    print(reduce(add,[1,2,3,4,5]))

NameError: name 'reduce' is not defined


In [30]: from functools import reduce

In [31]: def add(x,y):
    ...:     return x+y
    ...: print(reduce(add,[1,2,3,4,5]))
    ...: 
15
filter的用法

filter(f, [x1,x2,x3]) = [x1], f(x1)=True, f(x2)=False, f(x3)=False
注意: filter参数中f函数返回的是布尔类型的值, filter根据f(x1)返回的值是否是True而决定是否返回x1.

In [32]: def is_odd(n):
    ...:     return n % 2 == 1
    ...: 

In [33]: newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

In [34]: newlist
Out[34]: <filter at 0x1139f780>

In [35]: i = []

In [36]: for x in newlist:
    ...:     i.append(x)
    ...: print (i)
    ...: 
[1, 3, 5, 7, 9]
'''
关于filter()方法, python3和python2有一点不同
python2中返回的是过滤后的列表, 而python3中返回到是一个filter类
filter类实现了__iter__和__next__方法, 可以看成是一个迭代器, 有惰性运算的特性, 相对python2提升了性能, 可以节约内存.
'''
sorted() 函数对所有可迭代的对象进行排序操作。
# 如果是数字,默认按从小到到的顺序排列.
In [40]: sorted([36,5,11,9,22])
Out[40]: [5, 9, 11, 22, 36]

# 如果是字符串,默认先比较大写字符串的大小,然后再比较小写字符创的大小。都是从小到大顺序排列。
In [41]: sorted(['I','Hello','Gim', 'you', 'him', 'apple', 'banana'])
Out[41]: ['Gim', 'Hello', 'I', 'apple', 'banana', 'him', 'you']
匿名函数

关键字lambda表示匿名函数,冒号前面的x表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

In [42]: list(map(lambda x: x*x,[1,2,3,4,5,6,7,8]))
Out[42]: [1, 4, 9, 16, 25, 36, 49, 64]

In [43]: result = filter(lambda x: x>3, [1,2,3,4,5])
# 返回的是个可迭代对象
In [44]: result
Out[44]: <filter at 0x1139f588>

In [45]: list1 = []
    ...: for i in result:
    ...:     list1.append(i)
    ...:     

In [46]: list1
Out[46]: [4, 5]

'''
匿名函数的几个规则:
1. 不用函数名
2. 可以没有参数,可以有多个参数,参数可以带默认值。
3. 函数中只能写一个表达式。
4. 不用写return, 返回值就是表达式的结果

应用:
匿名函数一般应用于函数式编程。常和map, reduce 和 filter函数结合使用。
'''
对于视频中的做错题目的总结

PS:很多错误是由于py的版本差异造成的。

# L6 PROBLEM 9

In [153]:animals = {'a': 'aardvark', 'b': 'baboon', 'c': 'coati'}
In [154]:animals['d'] = 'donkey'

# 下面这条命令,答案显示的是False,其实是版本造成的
In [155]: animals.has_key('b')
Traceback (most recent call last):

  File "<ipython-input-155-700826fe47e9>", line 1, in <module>
    animals.has_key('b')

AttributeError: 'dict' object has no attribute 'has_key'

# L6 PROBLEM 10

In [157]:animals = { 'a': ['aardvark'], 'b': ['baboon'], 'c': ['coati']}
In [167]: def howMany(aDict):
     ...:     '''
     ...:     aDict: A dictionary, where all the values are lists.
     ...: 
     ...:     returns: int, how many values are in the dictionary.
     ...:     '''
     ...:     # Your Code Here
     ...:     return len(animals.keys()) + len(animals.values())


# L6 PROBLEM 11

In [180]: animals = { 'a': ['aardvark'], 'b': ['baboon'], 'c': ['coati']}
     ...: 
     ...: animals['d'] = ['donkey']
     ...: animals['d'].append('dog')
     ...: animals['d'].append('dingo')
     ...: 

Example usage:

In [181]: biggest(animals)
Out[181]: 'd'

答案:
In [182]: def biggest(aDict):
     ...:     '''
     ...:     aDict: A dictionary, where all the values are lists.
     ...: 
     ...:     returns: The key with the largest number of values associated with it
     ...:     '''
     ...:     result = None
     ...:     biggestValue = 0
     ...:     for key in aDict.keys():
     ...:         if len(aDict[key]) >= biggestValue:
     ...:             result = key
     ...:             biggestValue = len(aDict[key])
     ...:     return result
     ...: 

参考链接:
Python 内置函数
Python map/reduce/filter/sorted函数以及匿名函数
6.00.1X 计算机科学和PYTHON编程导论(自主模式)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容