遞歸
In [1]: def factl(n):
...: res = 1
...: while n > 1:
...: res = res * n
...: n -= 1
...: return res
...:
# 寫(xiě)成遞歸函數(shù)
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)
元組、字符串、列表、字典練習(xí)
元組
元組用圓括號(hào)標(biāo)記。組中只包含一個(gè)元素時(shí),需要在元素后面添加逗號(hào)。元組的一個(gè)特性是沒(méi)有重復(fù)的元素。其他特性如下:
>>> tup1 = ()
>>> tup1
()
>>> tup1 = (12,)
>>> tup1
(12,)
# 元組和字符串類(lèi)似,可以通過(guò)下標(biāo)來(lái)進(jìn)行索引和切片
>>> tup1 = ('physics', 'chemistry', 1997, 2000)
>>> tup2 = (1, 2, 3, 4, 5, 6, 7 )
>>> tup1[2]
1997
>>> tup1[1:3]
('chemistry', 1997)
# 元組中的元素不允許修改,但是可以進(jìn)行連接組合以及刪除整個(gè)元組
>>> 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)
# 可以用+號(hào)來(lái)進(jìn)行連接
>>> tup5 = tup3+tup4
>>> tup5
(12, 34, 'abc', 'xyz', 56, 33)
# 元組刪除后,再打印會(huì)進(jìn)行報(bào)錯(cuò)
>>> del tup5
>>> tup5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'tup5' is not defined
#元組的一些內(nèi)置函數(shù)如下:
len(tuple)
計(jì)算元組元素個(gè)數(shù)。
max(tuple)
返回元組中元素最大值。
min(tuple)
返回元組中元素最小值。
字符串
在python中字符串是最常見(jiàn)的類(lèi)型,可以用單引號(hào)或雙引號(hào)來(lái)創(chuàng)建。
# 可以對(duì)字符串進(jìn)行索引和切片
#需要在字符中使用特殊字符時(shí),python用反斜杠(\)轉(zhuǎn)義字符。
>>> 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'
# 字符串還可以進(jìn)行運(yùn)算等
>>> a = 'hello'
>>> b = 'timekiller'
>>> a + b
'hellotimekiller'
>>> a * 2
'hellohello'
列表
列表中的每個(gè)元素都分配一個(gè)數(shù)字 - 它的位置,或索引,第一個(gè)索引是0,第二個(gè)索引是1,依此類(lèi)推。
>>> list1 = ['my','python',12, 23]
>>> list1[0]
'my'
>>> list1[2]
12
>>> list1[1:3]
['python', 12]
# 使用append來(lái)添加元素,只能單個(gè)追加
>>> list = []
>>> list.append('Google')
>>> list.append('Tecent')
>>> list
['Google', 'Tecent']
# 還可以進(jìn)行刪除列表元素
>>> 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
其他一些列表中的方法如下:
| 方法 | 說(shuō)明 |
|---|---|
| list.append(obj) | 在列表末尾添加新的對(duì)象 |
| list.count(obj) | 統(tǒng)計(jì)某個(gè)元素在列表中出現(xiàn)的次數(shù) |
| list.extend(seq) | 在列表末尾一次性追加另一個(gè)序列中的多個(gè)值(用新列表擴(kuò)展原來(lái)的列表) |
| list.index(obj) | 從列表中找出某個(gè)值第一個(gè)匹配項(xiàng)的索引位置 |
| list.insert(index, obj) | 將對(duì)象插入列表 |
| list.pop([index=-1]) | 移除列表中的一個(gè)元素(默認(rèn)最后一個(gè)元素),并且返回該元素的值 |
| list.remove(obj) | 移除列表中某個(gè)值的第一個(gè)匹配項(xiàng) |
| list.reverse() | 反向列表中元素 |
| list.sort(cmp=None, key=None, reverse=False) | 對(duì)原列表進(jìn)行排序 |
字典
字典是另一種可變?nèi)萜髂P?,且可存?chǔ)任意類(lèi)型對(duì)象。
字典的每個(gè)鍵值 key=>value 對(duì)用冒號(hào) : 分割,每個(gè)鍵值對(duì)之間用逗號(hào) , 分割,整個(gè)字典包括在花括號(hào) {} 中。
>>> dict = {'alice':1992,'bob':1989,'beth':1995}
>>> dict
{'alice': 1992, 'bob': 1989, 'beth': 1995}
>>> type(dict)
<class 'dict'>
# 通過(guò)鍵來(lái)訪問(wèn)字典中的元素
>>> dict['alice']
1992
# 通過(guò)增加鍵值對(duì)增加字典中的元素
>>> dict['dylan']=1997
>>> dict
{'alice': 1992, 'bob': 1989, 'beth': 1995, 'dylan': 1997}
# 通過(guò)鍵刪除字典中的元素
>>> del dict['bob']
>>> dict
{'alice': 1992, 'beth': 1995, 'dylan': 1997}
# 創(chuàng)建時(shí)如果同一個(gè)鍵被賦值兩次,后一個(gè)值會(huì)被記住
>>> dict1 = {'name':'zara','age':7,'name':'manni'}
>>> dict1
{'name': 'manni', 'age': 7}
其他需要記住的是:鍵不允許出現(xiàn)兩次,鍵值必須不可變。
生成器和迭代器
1、生成器。
在Python中,這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱(chēng)為生成器:generator。要?jiǎng)?chuàng)建一個(gè)generator,可以通過(guò)把一個(gè)列表生成式的[]改成(),就創(chuàng)建了一個(gè)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
# 可以通過(guò)for循環(huán)來(lái)進(jìn)行調(diào)用
In [9]: for n in g:
...: print(n)
...:
4
9
16
25
36
49
64
81
要理解generator的工作原理,它是在for循環(huán)的過(guò)程中不斷計(jì)算出下一個(gè)元素,并在適當(dāng)?shù)臈l件結(jié)束for循環(huán)。對(duì)于函數(shù)改成的generator來(lái)說(shuō),遇到return語(yǔ)句或者執(zhí)行到函數(shù)體最后一行語(yǔ)句,就是結(jié)束generator的指令,for循環(huán)隨之結(jié)束。
# 請(qǐng)注意區(qū)分普通函數(shù)和generator函數(shù),普通函數(shù)調(diào)用直接返回結(jié)果:
In [10]: f = abs(-6)
In [11]: f
Out[11]: 6
# generator函數(shù)的“調(diào)用”實(shí)際返回一個(gè)generator對(duì)象:
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循環(huán)的對(duì)象統(tǒng)稱(chēng)為可迭代對(duì)象:Iterable,一類(lèi)是集合數(shù)據(jù)類(lèi)型,如list、tuple、dict、set、str等;一類(lèi)是generator,包括生成器和帶yield的generator function。
可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)值的對(duì)象稱(chēng)為迭代器:Iterator,它們表示一個(gè)惰性計(jì)算的序列。
# 集合數(shù)據(jù)類(lèi)型如list、dict、str等是Iterable但不是Iterator,不過(guò)可以通過(guò)iter()函數(shù)獲得一個(gè)Iterator對(duì)象。
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 以及匿名函數(shù)
map的功能:map(f, [x1,x2,x3]) = [f(x1), f(x2), f(x3)],3.x的版本返回的是個(gè)迭代器
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() 函數(shù)已經(jīng)被從全局名字空間里移除了,它現(xiàn)在被放置在 fucntools 模塊里,
#如果想要使用它,則需要通過(guò)引入 functools 模塊來(lái)調(diào)用 reduce() 函數(shù):
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參數(shù)中f函數(shù)返回的是布爾類(lèi)型的值, filter根據(jù)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]
'''
關(guān)于filter()方法, python3和python2有一點(diǎn)不同
python2中返回的是過(guò)濾后的列表, 而python3中返回到是一個(gè)filter類(lèi)
filter類(lèi)實(shí)現(xiàn)了__iter__和__next__方法, 可以看成是一個(gè)迭代器, 有惰性運(yùn)算的特性, 相對(duì)python2提升了性能, 可以節(jié)約內(nèi)存.
'''
sorted() 函數(shù)對(duì)所有可迭代的對(duì)象進(jìn)行排序操作。
# 如果是數(shù)字,默認(rèn)按從小到到的順序排列.
In [40]: sorted([36,5,11,9,22])
Out[40]: [5, 9, 11, 22, 36]
# 如果是字符串,默認(rèn)先比較大寫(xiě)字符串的大小,然后再比較小寫(xiě)字符創(chuàng)的大小。都是從小到大順序排列。
In [41]: sorted(['I','Hello','Gim', 'you', 'him', 'apple', 'banana'])
Out[41]: ['Gim', 'Hello', 'I', 'apple', 'banana', 'him', 'you']
匿名函數(shù)
關(guān)鍵字lambda表示匿名函數(shù),冒號(hào)前面的x表示函數(shù)參數(shù)。
匿名函數(shù)有個(gè)限制,就是只能有一個(gè)表達(dá)式,不用寫(xiě)return,返回值就是該表達(dá)式的結(jié)果。
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])
# 返回的是個(gè)可迭代對(duì)象
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]
'''
匿名函數(shù)的幾個(gè)規(guī)則:
1. 不用函數(shù)名
2. 可以沒(méi)有參數(shù),可以有多個(gè)參數(shù),參數(shù)可以帶默認(rèn)值。
3. 函數(shù)中只能寫(xiě)一個(gè)表達(dá)式。
4. 不用寫(xiě)return, 返回值就是表達(dá)式的結(jié)果
應(yīng)用:
匿名函數(shù)一般應(yīng)用于函數(shù)式編程。常和map, reduce 和 filter函數(shù)結(jié)合使用。
'''
對(duì)于視頻中的做錯(cuò)題目的總結(jié)
PS:很多錯(cuò)誤是由于py的版本差異造成的。
# L6 PROBLEM 9
In [153]:animals = {'a': 'aardvark', 'b': 'baboon', 'c': 'coati'}
In [154]:animals['d'] = 'donkey'
# 下面這條命令,答案顯示的是False,其實(shí)是版本造成的
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 內(nèi)置函數(shù)
Python map/reduce/filter/sorted函數(shù)以及匿名函數(shù)
6.00.1X 計(jì)算機(jī)科學(xué)和PYTHON編程導(dǎo)論(自主模式)