1. 程式人生 > 其它 >第一章:Python的資料結構、函式和檔案

第一章:Python的資料結構、函式和檔案

  • list

    list是一種有序的集合,可以隨時新增和刪除其中的元素。

    比如,列出班裡所有同學的名字,就可以用一個list表示:

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']
  • 用len()函式可以獲得list元素的個數:
>>> len(classmates)
3
  • 用append()函式可以往list中追加元素到末尾:
>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']
  • 用insert()函式可以在特定的位置插入元素:
>>> b_list
['foo', 'peekaboo', 'baz']
>>> b_list.insert(1, 'red')
>>> b_list
O['foo', 'red', 'peekaboo', 'baz']
  • 用pop()函式可以刪除list末尾的元素,要刪除指定位置的元素,用pop(i)方法,其中i是索引位置:
>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']
  • tuple

    另一種有序列表叫元組:tuple。tuple和list非常類似,但是tuple一旦初始化就不能修改。不可變的tuple有什麼意義?因為tuple不可變,所以程式碼更安全。如果可能,能用tuple代替list就儘量用tuple。

    tuple所謂的“不變”是說,tuple的每個元素,指向永遠不變。比如我在tuple裡面設定了一個list,我改變這個list是可以的,但是tuple所指向的這個list是永遠不會變的。

  • 用tuple可以將任意序列或迭代器轉換成元組:

In [5]: tuple([4, 0, 2])
Out[5]: (4, 0, 2)

In [6]: tup = tuple('string')

In [7]: tup
Out[7]: ('s', 't', 'r', 'i', 'n', 'g')
  • 如果你想將元組賦值給類似元組的變數,Python會試圖拆分等號右邊的值:
In [15]: tup = (4, 5, 6)

In [16]: a, b, c = tup

In [17]: b
Out[17]: 5
  • python允許從元組的開頭“摘取”幾個元素。它使用了特殊的語法*rest,這也用在函式簽名中以抓取任意長度列表的位置引數:
In [29]: values = 1, 2, 3, 4, 5

In [30]: a, b, *rest = values

In [31]: a, b
Out[31]: (1, 2)

In [32]: rest
Out[32]: [3, 4, 5]
  • 用count()函式可以統計某個值得出現頻率:
In [34]: a = (1, 2, 2, 2, 3, 4, 2)

In [35]: a.count(2)
Out[35]: 4
  • 用remove()函式會先尋找第一個值併除去:
In [52]: b_list
Out[52]: ['foo', 'red', 'baz', 'dwarf', 'foo']

In [53]: b_list.remove('foo')

In [54]: b_list
Out[54]: ['red', 'baz', 'dwarf', 'foo']
  • 用in()函式可以檢查列表是否包含某個值:
In [55]: 'dwarf' in b_list
Out[55]: True
  • 用extend()函式可以追加多個元素:
In [58]: x = [4, None, 'foo']

In [59]: x.extend([7, 8, (2, 3)])

In [60]: x
Out[60]: [4, None, 'foo', 7, 8, (2, 3)]
  • 用sort()函式可以將一個列表原地排序(不建立新的物件):
In [61]: a = [7, 2, 5, 1, 3]

In [62]: a.sort()

In [63]: a
Out[63]: [1, 2, 3, 5, 7]
  • sort()有一些選項,有時會很好用。其中之一是二級排序key,可以用這個key進行排序。例如,我們可以按長度對字串進行排序:
In [64]: b = ['saw', 'small', 'He', 'foxes', 'six']

In [65]: b.sort(key=len)

In [66]: b
Out[66]: ['He', 'saw', 'six', 'small', 'foxes']
  • bisect模組支援二分查詢,和bisect向已排序的列表插入值。bisect.bisect可以找到插入值後仍保證排序的位置,bisect.insort是向這個位置插入值:
In [67]: import bisect

In [68]: c = [1, 2, 2, 2, 3, 4, 7]

In [69]: bisect.bisect(c, 2)
Out[69]: 4

In [70]: bisect.bisect(c, 5)
Out[70]: 6

In [71]: bisect.insort(c, 6)

In [72]: c
Out[72]: [1, 2, 2, 2, 3, 4, 6, 7]
  • 用切邊可以選取大多數序列型別的一部分,切片的基本形式是在方括號中使用start:stop。(左閉右開)
In [73]: seq = [7, 2, 3, 7, 5, 6, 0, 1]

In [74]: seq[1:5]
Out[74]: [2, 3, 7, 5]
  • 切片也可以被序列賦值:
In [75]: seq[3:4] = [6, 3]
In [76]: seq
Out[76]: [7, 2, 3, 6, 3, 5, 6, 0, 1]
  • 切片也可以被序列賦值,start和stop都可以被省略,省略之後,分別預設序列的開頭和結尾,負數表明從後向前切片。
In [77]: seq[:5]
Out[77]: [7, 2, 3, 6, 3]

In [80]: seq[-6:-2]
Out[80]: [6, 3, 5, 6]
  • 在第二個冒號後面使用step,可以隔一個取一個元素:
In [81]: seq[::2]
Out[81]: [7, 3, 3, 6, 1]
  • 一個聰明的方法是使用-1,它可以將列表或元組顛倒過來:
In [82]: seq[::-1]
Out[82]: [1, 0, 6, 5, 3, 6, 3, 2, 7]
  • 迭代一個序列時,你可能想跟蹤當前項的序號,Python內建了一個enumerate函式,可以返回(i,value)元組序列。
for i, value in enumerate(collection):
# 簡單來說,這個enumerate就是為collection提供出了一個對應的的value(序列號)。
In [83]: some_list = ['foo', 'bar', 'baz']    #我設定出了一個some_list的list

In [84]: mapping = {}       #而這裡我設定出了一個空字典mapping{}

In [85]: for i, v in enumerate(some_list):
   ....:     mapping[v] = i       #而在這裡,我就將some_list中的i和value賦予給了字典mapping,其中的i是元素的索引,value是元素的值。
                                  #這裡的mapping[v] = i,是一個字典的寫法,如mapping[foo] = 0,依次迭代。
In [86]: mapping
Out[86]: {'bar': 1, 'baz': 2, 'foo': 0}
  • sorted函式可以從任意序列的元素返回一個新的排好序的列表:
In [87]: sorted([7, 1, 2, 6, 0, 3, 2])
Out[87]: [0, 1, 2, 2, 3, 6, 7]

In [88]: sorted('horse race')
Out[88]: [' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's']
  • zip函式可以將多個列表、元組或其它序列成對組合成一個元組列表:
In [89]: seq1 = ['foo', 'bar', 'baz']

In [90]: seq2 = ['one', 'two', 'three']

In [91]: zipped = zip(seq1, seq2)

In [92]: list(zipped)
Out[92]: [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]
  • zip可以處理任意多的序列,元素的個數取決於最短的序列:
In [93]: seq3 = [False, True]

In [94]: list(zip(seq1, seq2, seq3))
Out[94]: [('foo', 'one', False), ('bar', 'two', True)]
  • zip的常見用法之一是同時迭代多個序列,可能結合enumerate使用:
In [95]: for i, (a, b) in enumerate(zip(seq1, seq2)):      #我要將zip(seq1,seq2)跟蹤當前項的序號,返回(i,(a,b))元組序列,
   ....:     print('{0}: {1}, {2}'.format(i, a, b))        #str.format()函式:格式化字串的函式,使用方法見下。
   ....:
'''
>>>"{} {}".format("hello", "world")    # 不設定指定位置,按預設順序
'hello world'
 
>>> "{0} {1}".format("hello", "world")  # 設定指定位置
'hello world'
 
>>> "{1} {0} {1}".format("hello", "world")  # 設定指定位置
'world hello world'
'''
0: foo, one
1: bar, two
2: baz, three
  • 給出一個“被壓縮的”序列,zip可以被用來解壓序列。也可以當作把行的列表轉換為列的列表。這個方法看起來有點神奇:
In [96]: pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'),
   ....:             ('Schilling', 'Curt')]

In [97]: first_names, last_names = zip(*pitchers)

In [98]: first_names
Out[98]: ('Nolan', 'Roger', 'Schilling')

In [99]: last_names
Out[99]: ('Ryan', 'Clemens', 'Curt')
  • reversed()函式可以從後向前迭代一個序列,切記reversed()是一個生成器(後面詳細介紹),只有實體化(即列表或for迴圈)之後才能建立翻轉的序列:
In [100]: list(reversed(range(10)))
Out[100]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
  • 字典

    字典可能是Python最為重要的資料結構。它更為常見的名字是雜湊對映或關聯陣列。它是鍵值對的大小可變集合,鍵和值都是Python物件。建立字典的方法之一是使用尖括號,用冒號分隔鍵和值:

In [101]: empty_dict = {}

In [102]: d1 = {'a' : 'some value', 'b' : [1, 2, 3, 4]}

In [103]: d1
Out[103]: {'a': 'some value', 'b': [1, 2, 3, 4]}
  • 你可以像訪問列表或元組中的元素一樣,訪問、插入或設定字典中的元素;可以用檢查列表和元組是否包含某個值的方法,檢查字典中是否包含某個鍵;還可以用之前講過的del關鍵字或pop方法(返回值的同時刪除鍵)刪除值:
In [104]: d1[7] = 'an integer'
In [105]: d1
Out[105]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
In [106]: d1['b']
Out[106]: [1, 2, 3, 4]

In [108]: d1[5] = 'some value'

In [109]: d1
Out[109]: 
{'a': 'some value',
 'b': [1, 2, 3, 4],
 7: 'an integer',
 5: 'some value'}

In [110]: d1['dummy'] = 'another value'

In [111]: d1
Out[111]: 
{'a': 'some value',
 'b': [1, 2, 3, 4],
 7: 'an integer',
 5: 'some value',
 'dummy': 'another value'}

In [112]: del d1[5]

In [113]: d1
Out[113]: 
{'a': 'some value',
 'b': [1, 2, 3, 4],
 7: 'an integer',
 'dummy': 'another value'}

In [114]: ret = d1.pop('dummy')

In [115]: ret
Out[115]: 'another value'

In [116]: d1
Out[116]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
  • key和values是字典的鍵和值的迭代器方法。雖然鍵值對沒有順序,這兩個方法可以用相同的順序輸出鍵和值:
In [116]: d1
Out[116]: {'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
In [117]: list(d1.keys())
Out[117]: ['a', 'b', 7]

In [118]: list(d1.values())
Out[118]: ['some value', [1, 2, 3, 4], 'an integer']
  • 用update方法可以將一個字典與另一個融合:
In [119]: d1.update({'b' : 'foo', 'c' : 12})

In [120]: d1
Out[120]: {'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}
  • 常常,你可能想將兩個序列配對組合成字典。下面是一種寫法:
mapping = {}
for key, value in zip(key_list, value_list):
    mapping[key] = value

因為字典本質上是2元元組的集合,dict可以接受2元元組的列表:

In [121]: mapping = dict(zip(range(5), reversed(range(5))))    
#reversed 函式返回一個反轉的迭代器,seq -- 要轉換的序列,可以是 tuple, string, list 或 range。

In [122]: mapping
Out[122]: {0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
  • 預設值