計(jì)算機(jī)科學(xué)和Python編程導(dǎo)論week3

遞歸
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)論(自主模式)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 若想技術(shù)精進(jìn),當(dāng)然得把基礎(chǔ)知識(shí)打得牢牢的。 廖雪峰的官方網(wǎng)站 python3教程,該網(wǎng)站提供的教程淺顯易懂,還附帶...
    布口袋_天晴了閱讀 555評(píng)論 0 1
  • 列表生成式 函數(shù)的參數(shù)類(lèi)型 lambda函數(shù) map, reduce, filter, sorted函數(shù) eval...
    山陰少年閱讀 394評(píng)論 0 0
  • 1 高級(jí)特性 1.1 切片 取一個(gè)list或tuple的部分元素是非常常見(jiàn)的操作。 輸出結(jié)果: 1.2 迭代 在P...
    Claire_wu閱讀 411評(píng)論 0 0
  • 與有些人的緣分,總是冥冥注定,她沒(méi)有早一些也沒(méi)有晚一些,在你困難的時(shí)候與你做朋友,在你困惑的時(shí)候和你一起交流,在你...
    w尺素寸心閱讀 334評(píng)論 0 1
  • 如果站在電線桿子上跳舞, 會(huì)是什么滋味, 我這樣問(wèn)過(guò)自己。 我不敢去試。 這種滋味肯定很爽, 肯定會(huì)被很多人當(dāng)做白...
    薄涼人閱讀 404評(píng)論 0 0

友情鏈接更多精彩內(nèi)容