《Python程序設計與算法基礎教程(第二版)》江紅 餘青松,第十一章課後習題答案


一些知識點總結和幾個例題

一:二分查找法,冒泡、選擇、插入、歸併、快速排序算法

我把這幾個例題中的查找算法和排序算法,把自己對它們的理解總結了一下:
Python 關於下標的運用技巧(二分查找法,冒泡、選擇、插入、歸併、快速排序算法)

二:數組

import array

array.array(typecode [, initializer])
  • typecode:array對象中數據元素的類型
    創建array對象時必須指定其元素類型typecode,且其元素只能爲該類型,否則將導致TypeError
  • initializer:爲初始化數據序列或可迭代對象

例11.15

>>> import array
>>> a = array.array('b', (1, 2, 3, 4, 5))
>>> a[1] = 66
>>> a[1:]
array('b', [66, 3, 4, 5])
>>> a[0] = 'zgh'
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    a[0] = 'zgh'
TypeError: an integer is required (got type str)

下表來自https://docs.python.org/3.5/library/array.html#module-array
在這裏插入圖片描述
三:棧和隊列(collections.deque)

  • collections模塊中的deque對象雙端隊列
    支持從任意一端增加和刪除元素。
  • deque是線程安全的,內存高效的隊列,它被設計爲從兩端追加和彈出都非常快
import collections

collections.deque([iterable [, maxlen]])
  • iterable:初始元素
  • maxlen:指定隊列長度(默認無限制)
deque對象dq支持的方法:
dq.append(x) 在右端添加元素x
dq.appendleft(x) 在左端添加元素x
dq.pop() 從右端彈出元素。若隊列中無元素,則導致IndexError
dq.popleft() 從左端彈出元素。若隊列中無元素,則導致IndexError
dq.extend(iterable) 在右端添加序列iterable中的元素
dq.extendleft(iterable) 在左端添加序列iterable中的元素
dq.remove(value) 移除第一個找到的x。若未找到,則導致IndexError
dq.count(x) 返回元素x在隊列中出現的個數
dq.clear() 清空隊列,刪除所有元素
dq.reverse() 反轉
dq.rotate(n) 如果n>0,則所有元素向右移動n個位置(循環),否則向左

例11.17(讀取文件,返回文件最後的n行內容)

import collections

def tail(filename, n = 10):
    'Return the last n lines of a file'
    with open(filename) as f:
        return collections.deque(f, n)

if __name__ == '__main__':
    path = r'test.py'
    dq = tail(path, n = 2)
    print(dq.popleft())
    print(dq.popleft())

輸出:

    print(dq.popleft())

    print(dq.popleft())

若將代碼中的這一句改爲dq = tail(path, n = 5)
再看輸出:

if __name__ == '__main__':

    path = r'test.py'

例11.18(deque作爲棧)

  • 入棧:deque的append()方法
  • 出棧:deque的pop()方法
>>> from collections import deque
>>> dq = deque()
>>> dq.append(1)
>>> dq.append(2)
>>> dq.append(3)
>>> dq.pop()
3
>>> dq.pop()
2
>>> dq.pop()
1

例11.16(用列表list實現棧)

  • list.append()入棧
  • list.pop()出棧
class Stack:
    def __init__(self, size = 16):
        self.stack = []
    def push(self, obj):
        self.stack.append(obj)
    def pop(self):
        try:
            return self.stack.pop()
        except IndexError as e:
            print("stack is empty")
    def __str__(self):
        return str(self.stack)

def main():
    stack = Stack()
    #1,2先後入棧
    stack.push(1)
    stack.push(2)
    print(stack)
    #出棧
    stack.pop()
    print(stack)
    stack.pop()
    print(stack)
    stack.pop()
    print(stack)

if __name__ == '__main__':main()

輸出:

[1, 2]
[1]
[]
stack is empty
[]

例11.19(deque作爲隊列)

  • 進隊:deque的append()方法
  • 出隊:deque的popleft()方法
>>> from collections import deque
>>> dq = deque()
>>> dq.append(1)
>>> dq.append(2)
>>> dq.append(3)
>>> dq.popleft()
1
>>> dq.popleft()
2
>>> dq.popleft()
3

四:集合

  • 可變集合對象 set
    set()
    set(iterable)
  • 不可變集合對象 frozenset
    frozenset()
    frozenset(iterable)
  1. 集合中的元素不可重複,且無序,其存儲依據對象的hash碼
    hash碼是依據對象的值計算出來的一個唯一的值
    一個對象的hash值可以使用內置函數hash()獲得
  2. 所有的內置不可變對象,都是可hash對象
    可hash對象,即實現了__hash__()的對象
    bool、int、float、complex、str、tuple、frozenset
  3. 所有內置可變對象,都是非hash對象
    list、dict、set
    因爲可變對象的值可以變化,故無法計算唯一的hash值

在集合中可以包含內置不可變對象,不能包含內置可變對象

例11.20(創建集合對象示例)

集合:無序、不可重複

>>> {1, 2, 1}
{1, 2}

在集合中,重複元素,保留前面的

>>> {'a', 1, True, False, 0}
{False, 1, 'a'}

在集合中可以包含內置不可變對象,不能包含內置可變對象(list、dict、set)

>>> {'zgh', [6,6,6]}
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    {'zgh', [6,6,6]}
TypeError: unhashable type: 'list'

>>> {'zgh', {6, 6, 6}}
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    {'zgh', {6, 6, 6}}
TypeError: unhashable type: 'set'

>>> {'zgh', {'sex':'male'}}
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    {'zgh', {'sex':'male'}}
TypeError: unhashable type: 'dict'

例11.21(集合解析表達式)

>>> {i for i in range(5)}
{0, 1, 2, 3, 4}
>>> {2**i for i in range(5)}
{1, 2, 4, 8, 16}
>>> {x**2 for x in [1, 1, 2]}
{1, 4}
  1. 判斷元素x是否在集合s是否存在:
  • x in s 如果爲True,則表示存在
  • x not in s 如果爲True,則表示不存在
  1. 集合的運算:並集、交集、差集、對稱差集
運算符 說明
s1 | s2 | ... 返回 s1、s2…的並集
s1 & s2 | ... 返回 s1、s2…的交集
s1 - s2 - ... 返回 s1、s2…的差集
s1 ^ s2 返回 s1、s2 的對稱差集
  1. 集合的對象方法:
方法 說明
s1.union(s2, ...) 返回集合s1、s2…的並集
s1.update(s2, ...) 返回集合s1、s2…的並集,s1 |= (s2 | ...) (可變集合的方法)
s1.intersection(s2, ...) 返回集合s1、s2…的交集
s1.intersection_update(s2, ...) 返回集合s1、s2…的交集,s1 &= (s2 & ...) (可變集合的方法)
s1.difference(s2, ...) 返回集合s1、s2…的差集
s1.difference_update(s2, ...) 返回集合s1、s2…的差集,s1 -= (s2 - ...) (可變集合的方法)
s1.symmetric_difference(s2) 返回集合s1、s2的對稱差集
s1.symmetric_difference_update(s2) 返回集合s1、s2的對稱差集,s1 ^= (s2) (可變集合的方法)
>>> s1 = {1, 2, 3}
>>> s2 = {2, 3, 4}

>>> '''並集'''
>>> s1 | s2
{1, 2, 3, 4}
>>> s1.union(s2)
{1, 2, 3, 4}

>>> '''交集'''
>>> s1 & s2
{2, 3}
>>> s1.intersection(s2)
{2, 3}

>>> '''差集'''
>>> s1 - s2
{1}
>>> s2 - s1
{4}
>>> s1.difference(s2)
{1}

>>> '''對稱差集'''
>>> s1 ^ s2
{1, 4}
>>> s1.symmetric_difference(s2)
{1, 4}
  1. 集合的比較運算:相等、子集、超集
運算符 說明
s1 == s2 s1和s2的元素相同
s1 != s2 s1和s2的元素不完全相同
s1 < s2 s1是s2的純子集
s1 <= s2 s1是s2的子集
s1 >= s2 s1是s2的超集
s1 > s2 s1是s2的純超集
方法 說明
s1.isdisjoint(s2) 如果集合s1和s2沒有共同元素,返回True
s1.issubset(s2) 如果集合s1是s2的子集,返回True
s1.issuperset(s2) 如果集合s1是s2的超集,返回True
  1. 集合的長度、最大值、最小值、元素和
    len()
    max()
    min()
    sum() 如果元素有非數值類型(數值類型:int、float、bool、complex),則求和將導致TypeError

  2. 可變集合 set 的常用方法:

set的方法 說明
s.add(x) 把對象x添加到集合s
s.remove(x) 從集合s中移除對象x,若不存在,則導致KeyError
s.discard(x) 從集合s中移除對象x(如果存在)
s.pop() 從集合s中隨機彈出一個元素,如果s爲空,則導致KeyError
s.clear() 清空集合s

五:字典

  • 字典(dict)是一組鍵/值對的數據類型
    字典的鍵必須是可hash對象
  • 每個鍵對應於一個值
  • 在字典中,鍵不能重複,根據鍵可以查詢到值

字典的定義:

  1. dict()
    創建一個空字典
>>> {}
{}

>>> dict()
{}
  1. dict(**kwargs)
    使用關鍵字參數創建一個新的字典,此方法最緊湊
>>> dict(baidu = 'baidu.com', google = 'google.com')
{'baidu': 'baidu.com', 'google': 'google.com'}
  1. dict(mapping)
    從一個字典對象創建一個新的字典
>>> {'a':'apple', 'b':'boy'}
{'a': 'apple', 'b': 'boy'}

>>> dict({'a':'apple', 'b':'boy'})
{'a': 'apple', 'b': 'boy'}
  1. dict(iterable)
    使用序列創建一個新的字典
>>> dict([('id','666'),('name','zgh')])
{'id': '666', 'name': 'zgh'}

>>> dict((('id','666'),('name','zgh')))
{'id': '666', 'name': 'zgh'}

字典的訪問操作:

  1. d[key]
    返回鍵爲key的value,如果key不存在,則導致KeyError
>>> d = {1:'zgh', 2:'666'}
>>> d
{1: 'zgh', 2: '666'}
>>> d[1]
'zgh'
>>> d[2]
'666'
>>> d[3]
Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    d[3]
KeyError: 3
  1. d[key] = value
    設置d[key]的值爲value,如果key不存在,則添加鍵/值對
>>> d[3] = 'yes'
>>> d
{1: 'zgh', 2: '666', 3: 'yes'}
  1. del d[key]
    刪除字典元素,如果key不存在,則導致KeyError
>>> del d[2]
>>> d
{1: 'zgh', 3: 'yes'}

字典的視圖對象:

  1. d.keys()
    返回字典d的鍵key的列表
>>> d = dict(name = 'zgh', sex = 'male', age = '18')
>>> d
{'name': 'zgh', 'sex': 'male', 'age': '18'}
>>> d.keys()
dict_keys(['name', 'sex', 'age'])
  1. d.values()
    返回字典d的值value的列表
>>> d.values()
dict_values(['zgh', 'male', '18'])
  1. d.items()
    返回字典d的(key, value)對的列表
>>> d.items()
dict_items([('name', 'zgh'), ('sex', 'male'), ('age', '18')])

字典解析表達式:

>>> {key:value for key in "ABC" for value in range(3)}
{'A': 2, 'B': 2, 'C': 2}

>>> d = {'name':'zgh', 'sex':'male', 'age':'18'}
>>> {key:value for key,value in d.items()}
{'name': 'zgh', 'sex': 'male', 'age': '18'}
 
>>> {x:x*x for x in range(10) if x%2 == 0}
{0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

判斷字典鍵是否存在:

  1. key in d
    如果爲True,表示存在
>>> d = dict([('name', 'zgh'), ('sex', 'male'), ('age', '18')])
>>> d
{'name': 'zgh', 'sex': 'male', 'age': '18'}
>>> 'name' in d
True
  1. key not in d
    如果爲True,表示不存在
>>> 'names' in d
False

字典對象的長度和比較:

  1. len()
    獲取字典的長度
    雖然,字典對象也支持內置函數max()、min()、sum(),但是它們計算的是字典key,沒有意義
>>> d1 = {1:'food'}
>>> d2 = {1:'food', 2:'drink'}
>>> len(d1)
1
>>> len(d2)
2
  1. ==!=
    字典支持的比較運算中,只有==!=有意義
>>> d1 == d2
False
>>> d1 != d2
True

字典對象的方法:

字典對象的方法 說明
d.clear() 刪除所有元素
d.copy() 淺複製字典
d.get(k) 返回鍵k對應的值,如果key不存在,返回None
d.get(k,v) 返回鍵k對應的值,如果key不存在,返回v
d.pop(k) 如果鍵k存在,返回其值,並刪除該項目;否則將導致KeyError
d.pop(k,v) 如果鍵k存在,返回其值,並刪除該項目;否則返回v
d.setdefault(k,v) 如果鍵k存在,返回其值;否則添加項目k=v,v默認爲None
d.update([other]) 使用字典或鍵值對,更新或添加項目到字典d

六:collections模塊的數據結構

與字典相關

collections.defaultdict(function_factory)

用於構建類似dict的對象defaultdict

與dict的區別是,在創建defaultdict對象時可以使用構造函數參數function_factory指定其鍵值對中值的類型

import collections

collections.defaultdict([function_factory[, ...]])
  1. 其中,可選參數function_factory爲字典鍵值對中值的類型;其他可選參數同dict構造函數
  2. defaultdict實現了__missing__(key),即鍵不存在時返回值的類型(function_factory)對應的默認值,例如數值爲0、字符串爲'',list爲[]

鍵不存在時返回:值的類型(function_factory)對應的默認值,例如數值爲0

>>> import collections
>>> s = [('r', 1), ('g', 2), ('b', 3)]
>>>> dd = collections.defaultdict(int, s)
>>> dd['r']
1
>>> dd['g']
2
>>> dd['b']
3
>>> dd['z']
0

我們知道,在字典中鍵是不能重複的,而且鍵對應一個值
當鍵有重複的時候,後面的覆蓋前面的

>>> s1 = [('r', 1), ('g', 2), ('b', 3), ('r', 4), ('b', 5)]
>>> dict(s1)
{'r': 4, 'g': 2, 'b': 5}

那麼,
怎麼使字典中的鍵對應多個值呢?

>>> import collections
>>> s1 = [('r', 1), ('g', 2), ('b', 3), ('r', 4), ('b', 5)]
>>> dd1 = collections.defaultdict(list)
>>> for k,v in s1:
	dd1[k].append(v)

	
>>> list(dd1.items())
[('r', [1, 4]), ('g', [2]), ('b', [3, 5])]
>>> dd1.items()
dict_items([('r', [1, 4]), ('g', [2]), ('b', [3, 5])])

collections.OrderedDict([items])

是dict的子類,能夠記錄字典元素插入的順序

OrderedDict對象的元素保持插入的順序,在更新鍵的值時不改變順序;
若刪除項,然後插入與刪除項相同的鍵值對,則置於末尾

除了繼承dict的方法外,OrderedDict對象包括以下兩個方法:

OrderedDict對象的方法 說明
popitem(last=True) 彈出最後一個元素;如果last=False,則彈出第一個元素
move_to_end(key, last=True) 移動鍵key到最後;如果last=False,則移動到最前面
>>> import collections
>>> od = collections.OrderedDict(sorted(d.items()))
>>> od
OrderedDict([('age', '18'), ('name', 'guohao'), ('sex', 'female')])

>>> od.popitem()
('sex', 'female')
>>> od
OrderedDict([('age', '18'), ('name', 'guohao')])

>>> od['sex'] = 'male'
>>> od
OrderedDict([('age', '18'), ('name', 'guohao'), ('sex', 'male')])

>>> od.move_to_end('name')
>>> od
OrderedDict([('age', '18'), ('sex', 'male'), ('name', 'guohao')])

>>> od.move_to_end('name', False)
>>> od
OrderedDict([('name', 'guohao'), ('age', '18'), ('sex', 'male')])

與map相關

collections.ChainMap( * maps)

用於連接多個map

ChainMap對象內部包含多個map的列表(第一個map爲子map,其餘map爲父map),maps屬性返回這個列表。

>>> import collections
>>> m1 = {'a':1, 'b':2}
>>> m2 = {'a':2, 'x':3, 'y':4}
>>> m = collections.ChainMap(m1, m2)

ChainMap對象m除了支持字典映射的屬性和方法以外,還包含下列屬性和方法:

  1. m.maps
    屬性,返回m對象內部包含的map的列表
>>> m.maps
[{'a': 1, 'b': 2}, {'a': 2, 'x': 3, 'y': 4}]
  1. m.parents
    屬性,返回包含其父map的新的ChainMap對象,即ChainMap( * d.maps[1:])
>>> m.parents
ChainMap({'a': 2, 'x': 3, 'y': 4})
  1. m.new_child()
    方法,返回新的ChainMap對象,即ChainMap({}, * d.maps)
>>> m.new_child()
ChainMap({}, {'a': 1, 'b': 2}, {'a': 2, 'x': 3, 'y': 4})
  1. 在查詢時,首先查詢第一個map,如果沒有查到,則依次查詢其他map
>>> m['a']
1
>>> m['x']
3
  1. ChainMap只允許更新第一個map
>>> m['a'] = 99
>>> m['x'] = 10
>>> m
ChainMap({'a': 99, 'b': 2, 'x': 10}, {'a': 2, 'x': 3, 'y': 4})

更新鍵'x'的值,因爲夫map不能更新,故實際上是在子map中插入鍵值對

collections.Counter([iterable - or - mapping])

可選參數爲序列或字典map

創建Counter對象:

  • c = Counter()
    創建空的Counter對象
  • c = Counter('banana')
    基於序列創建Counter對象
  • c = Counter({'red':4, 'blue':2})
    基於字典映射
  • c = Counter(cats = 4, dogs = 8)
    基於命名參數
  1. Counter對象支持字典映射的屬性和方法,但查詢時如果鍵不存在將不會報錯,而是返回值0
>>> import collections
>>> c = collections.Counter({'r':3, 'g':2, 'b':1, 'y':4, 'w':3})
>>> c['green']
0
  1. c.elements()
    返回元素列表,各元素重複的次數爲其計數
>>> c.elements()
<itertools.chain object at 0x000001F92336F8C8>

>>> list(c.elements())
['r', 'r', 'r', 'g', 'g', 'b', 'y', 'y', 'y', 'y', 'w', 'w', 'w']
  1. c.most_common([n])
    返回計數值最大的n個元素的元組(元素,計數)列表
>>> c.most_common(2)
[('y', 4), ('r', 3)]
  1. c.subtract([iterable-or-mapping])
    元素的計數值減去序列或字典中對應元素的計數
>>> c.subtract('red')

>>> c
Counter({'y': 4, 'w': 3, 'r': 2, 'g': 2, 'b': 1, 'e': -1, 'd': -1})

與元組相關

namedtuple(typename, field_names, verbose = False, rename = False)

  • typename
    返回tuple的子類的類名
  • field_names
    是命名元組元素的名稱,必須爲合法的標識符
  • verbose
    當verbose爲True時,在創建命名元組後會打印類定義信息
  • rename
    當rename爲True時,如果field_names包含保留關鍵字,則自動命名爲_1、_2等

tuple是常用的數據類型,但只能通過索引訪問其元素

使用namedtuple的構造函數可以定義一個tuple的子類命名元組,namedtuple對象既可以使用元素名稱訪問其元素,也可以使用索引訪問

  1. 創建的命名元組的類可以通過_fields返回其字段屬性
>>> from collections import namedtuple
>>> p = namedtuple('Point', ['x', 'y'])
>>> print(p._fields)
('x', 'y')
>>> p.x = 11
>>> p.y = 22
>>> p.x + p.y
33
  1. namedtuple創建的類繼承自tuple,包含額外的三個方法:
    _make(iterable),從指定序列iterable構建命名元組對象
>>> t = [3, 4]
>>> p1 = p._make(t)
>>> p1
Point(x=3, y=4)
  1. _asdict()
    把命名元組對象轉換爲OrderDict對象
>>> p1._asdict()
OrderedDict([('x', 3), ('y', 4)])
  1. _replace(kwargs())
    創建新的命名元組對象,替換指定字段
>>> p1._replace(x=30)
Point(x=30, y=4)

>>> p1
Point(x=3, y=4)

UserDict、UserList和UserString對象

UserDict、UserList和UserString分別是dict、list、str的子類,一般用於創建其派生類

  • collections.UserDict([initialdata])
  • collections.UserList([list])
  • collections.UserString([sequence])

雖然可以直接基於dict、list、str創建派生類,但UserDict、UserList和UserString包括一個屬性成員—data,用於存放內容,因此可以更方便實現

以UserString爲例:

>>> from collections import *
>>> us = UserString('zgh')
>>> us.data
'zgh'

以UserList爲例:

>>> ul = UserList([1,1,3])
>>> ul.data
[1, 1, 3]

>>> ul.data[0]
1

以UserDict爲例:

>>> ud = UserDict({'name':'zgh', 'sex':'male', 'age':'18'})
>>> ud.data
{'name': 'zgh', 'sex': 'male', 'age': '18'}
>>> ud.data['name']
'zgh'

七:基於字典的通訊錄

實現一個簡單的基於字典數據結構的通訊管理系統,該系統採用JSON文件來保存數據

通訊錄設計爲字典:{name : tel}

有五個功能:

  1. 顯示通訊錄清單
    若通訊錄中無任何用戶信息,則提示:通訊錄爲空
  2. 查詢聯繫人資料
    若並不存在,則提示:是否新建聯繫人
  3. 插入新的聯繫人
    若聯繫人已存在,則提示:是否進行修改
  4. 刪除已有聯繫人
    若不存在此聯繫人,則提示:聯繫人不存在
  5. 退出
    保存通訊錄字典到addressbook.json中,退出循環

Python代碼:

"""簡易通訊錄程序"""

import os, json

address_book = {}
if os.path.exists("addressbook.json"):
    with open(r'addressbook.json', 'r', encoding='utf-8') as f:
        address_book = json.load(f)

while True:
    print("| --- 歡迎使用通訊錄程序 --- |")
    print("| --- 1:顯示通訊錄清單--- |")
    print("| --- 2:查詢聯繫人資料 --- |")
    print("| --- 3:插入新的聯繫人 -- |")
    print("| --- 4:刪除已有聯繫人 --- |")
    print("| --- 0:退出 --- |")
    choice = input('請選擇功能菜單:')
    if choice == '1':
        if(len(address_book) == 0):
            print("通訊錄爲空")
        else:
            for k,v in address_book.items():
                print("姓名 = {},聯繫電話 = {}".format(k, v))
        print()
    elif choice == '2':
        name = input("請輸入聯繫人姓名:")
        if (name not in address_book):
            yn = input("聯繫人不存在,是否增加用戶資料(Y/N):")
            if yn in ['Y', 'y']:
                tel = input("請輸入聯繫人電話:")
                address_book[name] = tel
        else:
            print("聯繫人信息:{} {}".format(name, address_book[name]))
        print()
    elif choice == '3':
        name = input("請輸入聯繫人姓名:")
        if (name in address_book):
            print("已存在聯繫人:{} {}".format(name, address_book[name]))
            yn = input("是否修改用戶資料(Y/N):")
            if yn in ['Y', 'y']:
                tel = input("請輸入聯繫人電話:")
                address_book[name] = tel
        else:
            tel = input("請輸入聯繫人電話:")
            address_book[name] = tel
        print()
    elif choice == '4':
        name = input('請輸入聯繫人姓名:')
        if (name not in address_book):
            print("聯繫人不存在:{}".format(name))
        else:
            tel = address_book.pop(name)
            print("刪除聯繫人:{} {}".format(name, tel))
        print()
    elif choice == '0':
        with open(r'addressbook.json', 'w', encoding='utf-8') as f:
            json.dump(address_book, f)
        break

運行Python模塊之前的json文件:

{"zgh": "15272502101", "xy": "110", "lcw": "888", "hq": "120"}

運行過程:

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:1
姓名 = zgh,聯繫電話 = 15272502101
姓名 = xy,聯繫電話 = 110
姓名 = lcw,聯繫電話 = 888
姓名 = hq,聯繫電話 = 120

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:2
請輸入聯繫人姓名:zgh
聯繫人信息:zgh 15272502101

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:2
請輸入聯繫人姓名:tf
聯繫人不存在,是否增加用戶資料(Y/N):y
請輸入聯繫人電話:000

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:2
請輸入聯繫人姓名:zwl
聯繫人不存在,是否增加用戶資料(Y/N):n

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:3
請輸入聯繫人姓名:zgh
已存在聯繫人:zgh 15272502101
是否修改用戶資料(Y/N):y
請輸入聯繫人電話:155

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:3
請輸入聯繫人姓名:zgh
已存在聯繫人:zgh 155
是否修改用戶資料(Y/N):n

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:3
請輸入聯繫人姓名:zwl
請輸入聯繫人電話:555

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:4
請輸入聯繫人姓名:zwl
刪除聯繫人:zwl 555

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:1
姓名 = zgh,聯繫電話 = 155
姓名 = xy,聯繫電話 = 110
姓名 = lcw,聯繫電話 = 888
姓名 = hq,聯繫電話 = 120
姓名 = tf,聯繫電話 = 000

| --- 歡迎使用通訊錄程序 --- |
| --- 1:顯示通訊錄清單--- |
| --- 2:查詢聯繫人資料 --- |
| --- 3:插入新的聯繫人 -- |
| --- 4:刪除已有聯繫人 --- |
| --- 0:退出 --- |
請選擇功能菜單:0

運行之後的json文件:

{"zgh": "155", "xy": "110", "lcw": "888", "hq": "120", "tf": "000"}

選擇題:1~5

1

>>> print(type({}))
<class 'dict'>

2

>>> print(type([]))
<class 'list'>

3

>>> print(type(()))
<class 'tuple'>

4

>>> dict1 = {}
>>> 
>>> dict2 = {2:6}
>>> 
>>> dict3 = {[1,2,3] : "user"}
Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    dict3 = {[1,2,3] : "user"}
TypeError: unhashable type: 'list'
>>> 
>>> dict4 = {(1,2,3) : "users"}

字典的鍵必須是可hash對象:bool、int、float、complex、str、tuple、frozenset
而 list、dict、set 是不可hash的

5

>>> dict1 = {}
>>> 
>>> dict2 = {1:8}
>>>> 
>>> dict3 = dict([2,4], [3,6])
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    dict3 = dict([2,4], [3,6])
TypeError: dict expected at most 1 arguments, got 2
>>> 
>>> dict4 = dict(([2,4], [3,6]))

填空題:1~8

1

>>> print(len({}))
0

2

>>> d = {1:'x', 2:'y', 3:'z'}
>>> del d[1]
>>> del d[2]
>>> d[1] = 'A'
>>> print(len(d))
2

3

>>> print(set([1, 2, 1, 2, 3]))
{1, 2, 3}

4

>>> fruits = {'apple':3, 'banana':4, 'pear':5}
>>> fruits['banana'] = 7
>>> print(sum(fruits.values()))
15

d.values()
返回字典d的值value的列表

5

>>> d1 = {1:'food'}
>>> d2 = {1:'食品', 2:'飲料'}
>>> d1.update(d2)
>>> print(d1[1])
食品

d.update([other])
使用字典或鍵值對,更新或添加項目到字典d

6

>>> names = ['Amy', 'Bob', 'Charlie', 'Daling']
>>> print(names[-1][-1])
g

names[-1] = ‘Daling’
names[-1][-1] = ‘Daling’[-1] = ‘g’

7

>>> s1 = {1, 2, 3}
>>> s2 = {3, 4, 5}
>>> 
>>> s1.update(s2)
>>> s1
{1, 2, 3, 4, 5}
>>> 
>>> s1.intersection_update(s2)
>>> s1
{3, 4, 5}
>>> 
>>> s1.difference_update(s2)
>>> s1
set()
>>> 
>>> s1.symmetric_difference_update(s2)
>>> s1
{3, 4, 5}
>>> 
>>> s1.add('x')
>>> s1
{3, 4, 5, 'x'}
>>> 
>>> s1.remove(1)
Traceback (most recent call last):
  File "<pyshell#67>", line 1, in <module>
    s1.remove(1)
KeyError: 1
>>> 
>>> s1.discard(3)
>>> s1
{4, 5, 'x'}
>>> 
>>> s1.clear()
>>> s1
set()

思考題:1~15

1

>>> list1 = {}
>>> list1[1] = 1
>>> list1['1'] = 3
>>> list1[1] += 2
>>> sum = 0
>>> for k in list1:
	sum += list1[k]

>>> print(sum)
6

2

>>> d = {1 : 'a', 2 : 'b', 3 : 'c'}
>>> del d[1]
>>> d[1] = 'x'
>>> del d[2]
>>> print(d)
{3: 'c', 1: 'x'}

3

>>> item_counter = {}
>>> def addone(item):
	if item in item_counter:
		item_counter[item] += 1
	else:
		item_counter[item] = 1

		
>>> addone('Apple')
>>> addone('Pear')
>>> addone('apple')
>>> addone('Apple')
>>> addone('kiwi')
>>> addone('apple')
>>> print(item_counter)
{'Apple': 2, 'Pear': 1, 'apple': 2, 'kiwi': 1}

4

>>> numbers = {}
>>> numbers[(1,2,3)] = 1
>>> numbers
{(1, 2, 3): 1}
>>> numbers[(2,1)] = 2
>>> numbers
{(1, 2, 3): 1, (2, 1): 2}
>>> numbers[(1,2)] = 3
>>> numbers
{(1, 2, 3): 1, (2, 1): 2, (1, 2): 3}
>>> sum = 0
>>> for k in numbers:
	sum += numbers[k]

>>> print(len(numbers),' ',sum,' ', numbers)
3   6   {(1, 2, 3): 1, (2, 1): 2, (1, 2): 3}

提示:

>>> (1,2) == (1,2)
True
>>> (1,2) == (2,1)
False

5

>>> d1 = {'a' : 1, 'b' : 2}
>>> d2 = d1
>>> d1['a'] = 6
>>> sum = d1['a'] + d2['a']
>>> print(sum)
12

d2 = d1
d1,d2指向同一個地址

6

>>> d1 = {'a' : 1, 'b' : 2}
>>> d2 = dict(d1)
>>> d1['a'] = 6
>>> sum = d1['a'] + d2['a']
>>> print(sum)
7

d2 = dict(d1)
d1,d2指向是不同的地址

7

>>> from collections import *
>>> m1 = {1 : 'a', 2 : 'b'}
>>> m2 = {2 : 'a', 3 : 'x', 4 : 'y'}
>>> m = ChainMap(m1, m2)
>>> print(m.maps, m.parents, m.new_child())
[{1: 'a', 2: 'b'}, {2: 'a', 3: 'x', 4: 'y'}] ChainMap({2: 'a', 3: 'x', 4: 'y'}) ChainMap({}, {1: 'a', 2: 'b'}, {2: 'a', 3: 'x', 4: 'y'})
>>> print(m[1], m[3])
a x
>>> m[1] = 'A'
>>> m[3] = 'X'
>>> print(m)
ChainMap({1: 'A', 2: 'b', 3: 'X'}, {2: 'a', 3: 'x', 4: 'y'})
  1. m.maps
    屬性,返回m對象內部包含的map的列表
  2. m.parents
    屬性,返回包含其父map的新的ChainMap對象,即ChainMap( * d.maps[1:])
  3. m.new_child()
    方法,返回新的ChainMap對象,即ChainMap({}, * d.maps)
  4. 在查詢時,首先查詢第一個map,如果沒有查到,則依次查詢其他map
  5. ChainMap只允許更新第一個map

8

>>> from collections import *
>>> c1 = Counter()
>>> print(c1)
Counter()
>>>
>>> c2 = Counter('banana')
>>> print(c2)
Counter({'a': 3, 'n': 2, 'b': 1})
>>> 
>>> c3 = Counter({'R':4, 'B':2})
>>> print(c3)
Counter({'R': 4, 'B': 2})
>>> 
>>> c4 = Counter(birds = 2, cats = 4, dog = 8)
>>> print(c4)
Counter({'dog': 8, 'cats': 4, 'birds': 2})
>>> 
>>> print(c4['flowers'], c4['cats'])
0 4
>>>
>>> print(list(c3.elements()))
['R', 'R', 'R', 'R', 'B', 'B']
>>> 
>>> print(c4.most_common(2))
[('dog', 8), ('cats', 4)]
>>>
>>>> c3.subtract('RGB')
>>> print(c3)
Counter({'R': 3, 'B': 1, 'G': -1})

創建Counter對象:

  • c = Counter()
    創建空的Counter對象
  • c = Counter('banana')
    基於序列創建Counter對象
  • c = Counter({'red':4, 'blue':2})
    基於字典映射
  • c = Counter(cats = 4, dogs = 8)
    基於命名參數
  1. Counter對象支持字典映射的屬性和方法,但查詢時如果鍵不存在將不會報錯,而是返回值0
  2. c.elements()
    返回元素列表,各元素重複的次數爲其計數
  3. c.most_common([n])
    返回計數值最大的n個元素的元組(元素,計數)列表
  4. c.subtract([iterable-or-mapping])
    元素的計數值減去序列或字典中對應元素的計數

9

>>> from collections import *
>>> dq = deque()
>>> dq.append('a')
>>> dq.append(2)
>>> dq.append('c')
>>> data = iter(dq)
>>> while True:
	try: i = next(data)
	except StopIteration: break
	print(i, end=' ')

	
a 2 c 
>>> print(dq.pop(), dq.pop(), dq.pop())
c 2 a
  1. dq.append(x)
    在右端添加元素x
  2. dq.pop() 從右端彈出元素。
    若隊列中無元素,則導致IndexError
  3. dq.popleft()
    從左端彈出元素。若隊列中無元素,則導致IndexError
  4. 使用內置函數iter(obj)可以返回一個迭代器
  5. 使用內置函數next()可以依次返回迭代器對象的下一個項目值

10

>>> from collections import *
>>> dq = deque()
>>> dq.append('a')
>>> dq.append(2)
>>> dq.append('c')
>>> print(dq.popleft(), dq.popleft(), dq.popleft())
a 2 c

11

>>> from collections import defaultdict
>>> s = [('r', 3), ('g', 2), ('b', 1)]
>>> dd = defaultdict(int, s)
>>> print(dd['b'], dd['w'])
1 0
>>> 
>>> s1 = [('r', 3), ('g', 2), ('b', 1), ('r', 5), ('b', 4)]
>>> dd1 = defaultdict(list)
>>> for k,v in s1:
	dd1[k].append(v)

	
>>> print(list(dd1.items()))
[((1, 2), []), ('r', [3, 5]), ('g', [2]), ('b', [1, 4])]
  1. 與dict的區別是,在創建defaultdict對象時可以使用構造函數參數function_factory指定其鍵值對中值的類型
  2. defaultdict實現了__missing__(key),即鍵不存在時返回值的類型(function_factory)對應的默認值,例如數值爲0、字符串爲'',list爲[]

此處,保有疑問,個人覺的print(list(dd1.items()))的運行結果應該是[ ('r', [3, 5]), ('g', [2]), ('b', [1, 4])],沒有弄懂((1, 2), [])從何處來?

12

>>> from collections import *
>>> d = {'red' : 3, 'green' : 4, 'blue' : 1}
>>> print(d.items(), sorted(d.items()))
dict_items([('red', 3), ('green', 4), ('blue', 1)]) [('blue', 1), ('green', 4), ('red', 3)]
>>> 
>>> od = OrderedDict(sorted(d.items()))
>>> print(od.popitem(), od.popitem(False))
('red', 3) ('blue', 1)
  1. 除了繼承dict的方法外,OrderedDict對象有一個方法:popitem(last=True)
    彈出最後一個元素;如果last=False,則彈出第一個元素 |

13

>>> from collections import *
>>> p = namedtuple('Point', ['x', 'y'])
>>> p.x = 1
>>> p.y = 2
>>> print(p._fields, p.x, p.y)
('x', 'y') 1 2
>>> 
>>> t = [10, 20]
>>> p1 = p._make(t)
>>> print(p1._asdict())
OrderedDict([('x', 10), ('y', 20)])
>>> 
>>> print(p1._replace(x=100), p1.x, p1.y)
Point(x=100, y=20) 1 2
  1. 創建的命名元組的類可以通過_fields返回其字段屬性
  2. namedtuple創建的類繼承自tuple,包含額外的三個方法:
    _make(iterable),從指定序列iterable構建命名元組對象
  3. _asdict()
    把命名元組對象轉換爲OrderDict對象
  4. _replace(kwargs())
    創建新的命名元組對象,替換指定字段

14

>>> import array
>>> arr1 = array.array('i', (1, 2, 3, 4, 5))
>>> arr1[1] = 22
>>> print(arr1, arr1[2:], type(arr1[1]))
array('i', [1, 22, 3, 4, 5]) array('i', [3, 4, 5]) <class 'int'>
>>> del arr1[2:]
>>> print(arr1, arr1.typecode, arr1.itemsize)
array('i', [1, 22]) i 4

15

>>> import array
>>> a = array.array('b', (3, 2))
>>> a.append(3)
>>> a.extend((3, 5))
>>> print(a, a.count(3))
array('b', [3, 2, 3, 3, 5]) 3
>>> a.frombytes(b'A1')
>>> a.fromlist([8, 9])
>>> print(a, a.index(3))
array('b', [3, 2, 3, 3, 5, 65, 49, 8, 9]) 0
>>> a.insert(0, 1)
>>> a.pop()
9
>>> a.remove(2)
>>> a.reverse()
>>> print(a.tolist())
[8, 49, 65, 5, 3, 3, 3, 1]

上機實踐:2~13

對於書中給的查找算法和排序算法

  • 查找算法:二分排序法
  • 排序算法:冒泡,選擇,插入,歸併,快排

我突發奇想,寫了以上算法中是如何玩轉下標的
Python 關於下標的運用技巧(二分查找法,冒泡、選擇、插入、歸併、快速排序算法)

2. 修改例11.3,在列表中順序查找特定數值的程序,設法從命令行參數中獲取要查詢的數據

import sys

def sequentialSearch(alist, item):
    pos = 0
    found = False
    while pos < len(alist) and not found:
        if alist[pos] == item:
            found = True
        else:
            pos += 1
    return found

if __name__ == '__main__':
    testlist = [1, 3, 33, 8, 37, 29, 32, 15, 5]
    item = float(sys.argv[1])
    print(sequentialSearch(testlist, item))
    

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

3. 修改例11.4,在列表中順序查找最大值和最小值的示例程序,設法從命令行參數中獲取測試列表的各元素

import sys

def max1(alist):
    pos = 0
    iMax = alist[0]
    while pos < len(alist):
        if alist[pos] > iMax:
            iMax = alist[pos]
        pos += 1
    return iMax

def min1(alist):
    pos = 0
    iMin = alist[0]
    while pos < len(alist):
        if alist[pos] < iMin:
            iMin = alist[pos]
        pos += 1
    return iMin

if __name__ == '__main__':
    alist = []
    for i in range(1, len(sys.argv)):
        alist.append(float(sys.argv[i]))
    print("最大值 = ", max1(alist))
    print("最小值 = ", min1(alist))

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

4. 修改例11.5,二分查找法的遞歸程序,設法從命令行參數中獲取測試列表的各元素以及所要查找的關鍵字

怎麼理解二分查找法的遞歸實現和非遞歸實現等算法,可以看一我的這篇文章
Python 關於下標的運用技巧(二分查找法,冒泡、選擇、插入、歸併、快速排序算法)

import sys

def _binarySearch(key, a, lo, hi):
    if lo >= hi:
        return -1
    mid = (lo + hi) // 2
    if(key < a[mid]):
        return _binarySearch(key, a, lo, mid)
    elif(key > a[mid]):
        return _binarySearch(key, a, mid+1, hi)
    else:
        return mid

def binarySearch(key, a):
    return _binarySearch(key, a, 0, len(a))

if __name__ == '__main__':
    a = []
    key = float(sys.argv[1])
    for i in range(2, len(sys.argv)):
        a.append(float(sys.argv[i]))
    print("關鍵字{0}位於列表索引(-1表示不存在):{1}".format(key, binarySearch(key, a)))

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

5. 修改例11.6,二分查找法的非遞歸程序,設法從命令行參數中獲取測試列表的各元素以及所要查找的關鍵字

import sys

def binarySearch(key, a):
    low = 0
    high = len(a) -1
    while low <= high:
        mid = (low + high)//2
        if(key > a[mid]):
            low = mid +1
        elif(key < a[mid]):
            high = mid -1
        else:
            return mid
    return -1 

if __name__ == '__main__':
    a = []
    key = float(sys.argv[1])
    for i in range(2, len(sys.argv)):
        a.append(float(sys.argv[i]))
    print("關鍵字{0}位於列表索引(-1表示不存在):{1}".format(key, binarySearch(key, a)))

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

6. 修改例11.8,冒泡排序算法程序,設法從命令行參數中獲取測試列表的各元素

import sys

def bubbleSort(a):
    for i in range(len(a)-1, -1, -1):
        for j in range(i):
            if a[j] > a[j+1]:
                a[j],a[j+1] = a[j+1],a[j]

def main():
    a = []
    for i in range(1, len(sys.argv)):
        a.append(float(sys.argv[i]))
    bubbleSort(a)
    print(a)

if __name__ == '__main__':main()

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

輸出:

[1.0, 3.0, 13.0, 26.0, 33.0, 45.0, 55.0, 68.0, 72.0, 83.0, 99.0]

7. 修改例11.9,選擇排序算法程序,設法從命令行參數中獲取測試列表的各元素

import sys

def selectionSort(a):
    for i in range(0, len(a)-1):
        for j in range(i+1, len(a)):
            if(a[j] < a[i]):
                a[i],a[j] = a[j],a[i]

def main():
    a = []
    for i in range(1, len(sys.argv)):
        a.append(float(sys.argv[i]))
    selectionSort(a)
    print(a)

if __name__ == '__main__':main()

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

輸出:

[1.0, 3.0, 13.0, 26.0, 33.0, 45.0, 55.0, 68.0, 72.0, 83.0, 99.0]

8. 修改例11.10,插入排序算法程序,設法從命令行參數中獲取測試列表的各元素

import sys

def insertSort(a):
    for i in range(1, len(a)):
        for j in range(i, 0, -1):
            if(a[j-1] > a[j]):
                a[j-1],a[j] = a[j],a[j-1]

def main():
    a = []
    for i in range(1, len(sys.argv)):
        a.append(float(sys.argv[i]))
    insertSort(a)
    print(a)

if __name__ == '__main__':main()

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

輸出:

[1.0, 3.0, 13.0, 26.0, 33.0, 45.0, 55.0, 68.0, 72.0, 83.0, 99.0]

9. 修改例11.11,歸併排序算法程序,設法從命令行參數中獲取測試列表的各元素

import sys

def merge(left, right):
    merged = []
    i, j = 0, 0
    left_len, right_len = len(left), len(right)
    while i < left_len and j < right_len:
        if left[i] <= right[j]:
            merged.append(left[i])
            i += 1
        else:
            merged.append(right[j])
            j += 1
    merged.extend(left[i:])
    merged.extend(right[j:])
    return merged

def mergeSort(a):
    if len(a) <= 1:
        return a
    mid = len(a) // 2
    left = mergeSort(a[:mid])
    right = mergeSort(a[mid:])
    return merge(left, right)

def main():
    a = []
    for i in range(1, len(sys.argv)):
        a.append(float(sys.argv[i]))
    print(mergeSort(a))

if __name__ == '__main__':main()

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

輸出:

[1.0, 3.0, 13.0, 26.0, 33.0, 45.0, 55.0, 68.0, 72.0, 83.0, 99.0]

10. 修改例11.12,快速排序算法程序,設法從命令行參數中獲取測試列表的各元素

import sys

def quickSort(a, low , high):
    i = low
    j = high
    if i >= j:
        return a
    key = a[i]
    while i < j:
        while i < j and a[j] >= key:
            j -= 1
        a[i] = a[j]
        while i < j and a[i] <= key:
            i += 1
        a[j] = a[i]
    a[i] = key
    quickSort(a, low, i-1)
    quickSort(a, j+1, high)

def main():
    a = []
    for i in range(1, len(sys.argv)):
        a.append(float(sys.argv[i]))
    quickSort(a, 0, len(a)-1)
    print(a)

if __name__ == '__main__':main()

涉及到命令行參數,一般有兩種執行方式

  1. 通過控制檯(cmd)
  2. 通過編輯器(就是你寫python代碼的工具)
    我寫這些小玩意,使用的是python自帶的IDLE,
    以IDLE(使用其他編輯器的,自己百度一下怎麼執行時輸入命令行參數)爲例:

    點擊Run,然後Run…Customized(有快捷鍵:shift+F5)
    輸入命令行參數即可

輸出:

[1.0, 3.0, 13.0, 26.0, 33.0, 45.0, 55.0, 68.0, 72.0, 83.0, 99.0]

11. 參考例11.42,實現namedtuple對象應用程序,讀取成績文件scores.csv的內容(學員、ID、語文、數學、外語和信息),顯示學員ID和平均成績

自己寫一個scores.csv文件:
csv文件:推薦以逗號分隔

zgh, 1, 100, 100, 100, 100
xy, 2, 99, 98, 90, 85
hq, 3, 90, 98, 80, 96
lcw, 4, 85, 88, 65, 90

python代碼:

from collections import *
import csv

Score = namedtuple('Score', 'name, id, chinese, math, english, computer')
for stu in map(Score._make, csv.reader(open("scores.csv", encoding = 'utf-8'))):
    score_average = (float(stu.chinese) + float(stu.math) + float(stu.math) + float(stu.computer)) / 4
    print(stu.id, score_average)

運行結果:

 1 100.0
 2 95.0
 3 95.5
 4 87.75

12. 創建由‘Monday’~‘Sunday’7個值組成的字典,輸出鍵列表、值列表以及鍵值列表

d = {1:'Monday', 2:'Tuesday', 3:'Wednesday', 4:'Thursday', 5:'Friday', 6:'Saturday', 7:'Sunday'}

#print(d.keys())
for k in d.keys():
    print(k, end=' ')
print()

#print(d.values())
for v in d.keys():
    print(v, end=' ')
print()

#print(d.items())
for i in d.items():
    print(i, end=' ')

運行結果:

1 2 3 4 5 6 7 
1 2 3 4 5 6 7 
(1, 'Monday') (2, 'Tuesday') (3, 'Wednesday') (4, 'Thursday') (5, 'Friday') (6, 'Saturday') (7, 'Sunday') 

13. 隨機生成10個0(包含)~10(包含)的整數,分別組成集合A和集合B,輸出A和B的內容、長度、最大值、最小值以及它們的並集、交集和差集

import random

def func():
    l = []
    for j in range(5):
        x = random.randint(1,10)
        l.append(x)
    return set(l)

A = func()
B = func()
print("集合的內容、長度、最大值、最小值分別爲:")
print(A, len(A), max(A), min(A))
print(B, len(B), max(B), min(B))
print("A和B的並集、交集和差集分別爲:")
print(A|B, A&B, A-B)   

某次運行效果:

集合的內容、長度、最大值、最小值分別爲:
{2, 4, 5, 7, 9} 5 9 2
{2, 4, 5, 8, 10} 5 10 2
A和B的並集、交集和差集分別爲:
{2, 4, 5, 7, 8, 9, 10} {2, 4, 5} {9, 7}

案例研究:程序運行時間度量分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章