《利用Python進行數據分析》 —— (2)

《利用Python進行數據分析》 —— (2)

本章主要介紹Python經常使用的數據結構和以及Python函數等基礎知識。python

3.1 數據結構與序列

3.1.1 元組

元祖是一種固定長度、不可變的Python對象序列數據結構

建立元組的方法:app

In [3]: tup1 = 1, 2, 3 # 直接

In [4]: tup2 = (1, 2, 3), (4, 5) # 用括號分割

In [5]: tup3 = tuple([1, 2, 3]) # 利用tuple函數將任意序列或迭代器進行轉化

In [6]: print(tup1, tup2, tup3)
(1, 2, 3) ((1, 2, 3), (4, 5)) (1, 2, 3)

元組一旦建立其各個位置上的對象沒法被修改。可是假如元組中的對象是可變的,即可以對其進行修改,eg:列表函數

In [15]: tup = tuple([[1,2], [3]])

In [16]: tup
Out[16]: ([1, 2], [3])

In [17]: tup[0].append(4)

In [18]: tup
Out[18]: ([1, 2, 4], [3])

能夠用+號鏈接元組來生成更長的元組。atom

3.1.1.1 元組拆包

若是將元組型的表達式賦值給變量,Python會對等式右邊的值進行拆包:設計

In [21]: tup = (1, 2, 3)

In [22]: a, b, c = tup # 簡單拆包

In [23]: print(a, b, c)
1 2 3

In [24]: tup1 = 4, 5, (6, 7)

In [25]: a, b, (c, d) = tup1 # 嵌套元組也行

In [26]: print(a, b, c, d)
4 5 6 7

使用這個功能,可以輕鬆的實現交換變量名rest

In [27]: a, b = 1, 2

In [28]: print(a, b)
1 2

In [29]: a, b = b, a # 進行交換

In [30]: print(a, b)
2 1

更爲高級的拆包功能,「*rest用於在函數調用時獲取任意長度的位置參數列表」rest變量名並非保留字,能夠替換。有時rest部分表明想要丟棄的數據,所以也能夠用_下劃線表明不想要的變量:code

In [32]: a, b, *rest = val

In [33]: print(a, b, rest)
1 2 [3, 4, 5, 6]
3.1.1.2 元組方法

元組方法不多,常見能夠使用的是count,用於統計某元素在元組中出現的次數。orm

3.1.2 列表

3.1.2.1 增長和刪除元素

Noteremove方法會定位第一個符合要求的值並移除它。(區別於C++)對象

使用 innot 能夠用於檢查一個值是否在列表中。

可是與字典,集合相比檢查列表是一個很是緩慢的過程,這是由於 Python 的手段是逐項檢查。而在字典和集合中 Python 是同時檢查全部元素(基於哈希表)

3.1.2.2 鏈接和聯合列表

在嘗試進行列表鏈接在一塊兒時,extend 是比 + 更高效的辦法。

3.1.2.4 二分搜索和已排序列表的維護

內建的 bisect 模塊實現了二分搜索和已排序列表的插值。

  • bisect.bisect會找到當前元素應當被插入的位置,並保持序列排序。
  • bisect.insort將元素直接插入到對應的位置。
In [63]: arr = [1, 2, 2, 2, 3, 4, 7]

In [64]: bisect.bisect(arr, 2) #二分查找
Out[64]: 4

In [65]: bisect.bisect(arr, 5)
Out[65]: 6

In [66]: bisect.insort(arr, 6) # 直接插入

In [67]: arr
Out[67]: [1, 2, 2, 2, 3, 4, 6, 7]

能夠發現bisect.bisect在有重複元素時指向的是最右邊的元素。所以在列表中存在重複元素時,能夠考慮以下幾個方法:

bisect.bisect_left bisect.insort_left

bisect.bisect_right bisect.insort_right

注意bisect方法並不會檢查序列是否有序(開銷過大),所以在使用前必定要排序(否則會出現錯誤答案)

3.1.2.5 切片

切片爲 [start : stop] 並不包括最後一個 stop 位置。所以切片的元素長度爲 stop - start

負數表明從後往前

切片還有一種語法爲:[start : stop : step]

其中 step 表明沒過多少步值取一個數,負數表明從後往前取

In [72]: arr
Out[72]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [73]: arr[::2]
Out[73]: [0, 2, 4, 6, 8]

In [74]: arr[::-2]
Out[74]: [9, 7, 5, 3, 1]

In [75]: arr[::-1] # 實現了翻轉
Out[75]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

3.1.3 內建序列函數

Python 中有許多序列函數,應當認真熟悉

3.1.3.1 enumerate

咱們有時須要遍歷一個序列的同時追蹤當前元素的索引,面對這種場景咱們能夠使用Python 內建的 enumerate 函數,返回 (i, value) 元組的序列。例如:

In [78]: for i, val in enumerate(arr):
    ...:     print("{0:d}, {1:d}".format(i, val))
0, 0
1, 1
2, 2
3, 3
4, 4
5, 5
6, 6
7, 7
8, 8
9, 9
3.1.3.3 zip

zip 能夠處理任意長度的序列,它生成列表的長度由最短的序列決定。

3.1.3.4 reversed

要記住 reversed 是一個生成器(後面詳細介紹),只有實體化(即列表或for循 環)以後才能建立翻轉的序列。(?? 不太懂先記錄)

3.1.4 字典

能夠經過 update 方法將兩個字典合併,可是若是有相同的鍵值,則它的值會被新值覆蓋

3.1.4.2 默認值

一般狀況下,可能會出現這樣的設計,咱們先判斷某個值是否存在於字典中假如不存在返回一個默認值:

if key in some_dict:
	value = some_dict[key]
else:
	value = default_value

例如,如今須要經過首字母將單詞分類,在沒有預設默認值的狀況下得用 if-else 分支:

In [123]: words = ['apple', 'bat', 'bar', 'atom', 'book']
In [124]: by_letter = {}
In [125]: for word in words:
.....: 	      letter = word[0]
.....:        if letter not in by_letter:
.....: 		      by_letter[letter] = [word]
.....:        else:
.....:            by_letter[letter].append(word)
.....:
In [126]: by_letter
Out[126]: {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}

經過setdefault能夠快速解決這個問題:

for word in words:
	letter = word[0]
	by_letter.setdefault(letterm, []).append(word) # 設置默認爲list

或者經過內建的defaultdict類實現默認值設置問題。傳遞類型或函數以生成每一個位置的默認值:

from collections import defaultdict
by_letter = defaultdict(list) # 設置默認類型爲list類型(能夠設置爲其餘類型)
for word in words:
	by_letter[word[0]].append(word)
3.1.4.3 有效的鍵類型

只須要注意幾點:值能夠是任何 Python 對象,可是鍵必須是不可變的對象,(整數、浮點型、 字符串)或元組(元組中的對象必須是不可變的

3.1.5 集合

  • 集合的初始化操做

    • set([1, 2, 2, 3, 4])
    • {1, 2, 2, 3, 4}
  • 和字典相似,集合中的元素必須是不可變對象,所以假如想要包含列表元素,須要轉化爲元組類型。

set

3.1.6 列表、集合和字典推導式

關於一維推導式,記住如下三個經典的便可:

  • [expr for val in collection if condition]

  • dict_comp = {key-expr : value-expr for value in collection if condition}

  • set_comp = {expr for value in collection if condition}

關於多維嵌套列表推導式,只須要記住:for 表達式的順序應與你寫嵌套 for 循環來代替列表推導式的順序一致。

3.2 函數

函數時對象,能夠將函數操做存在一個列表中,直接調用,以下圖所示:

In [99]: def f1(x):
    ...:     return x + 5

In [100]: def f2(x):
     ...:     return x ** 2

In [101]: def f3(x):
     ...:     return x * 3

In [102]: func = [f1, f2, f3]

In [103]: a = 1

In [107]: for funcs in func:
     ...:     a = funcs(a)

In [108]: a
Out[108]: 108
相關文章
相關標籤/搜索