天天看點

Python容器類型,有哪些使用小技巧?

作者:西安華清遠見

Python中提供了非常豐富的容器型資料類型,大家最為熟悉的有list、tuple、set、dict等。下面為大家分享一些使用這些類型的小技巧,希望幫助大家寫出更加Pythonic的代碼。

從字典中取最大

假設字典對象對應的變量名為my_dict。

取出最大值

max(my_dict.values())           

取值最大值的鍵

 max(my_dict, key=my_dict.get)           

取出最大值的鍵和值

  max(my_dict.items(), key=lambda x: x[1])           

 import operatormax(my_dict.items(), key=operator.itemgetter(1))           

說明:上面用到了operator子產品的itemgetter函數,這個函數的的作用如下所示。在上面的代碼中,itemgetter幫我們擷取到了二進制組中的第2個元素。

 def itemgetter(*items):
      if len(items) == 1:
          item = items[0]
          def g(obj):
              return obj[item]
      else:
          def g(obj):
              return tuple(obj[item] for item in items)
      return g           

統計清單元素出現次數

假設清單對象對應的變量名為my_list。

{x: my_list.count(x) for x in set(my_list)}           

from itertools import groupby{key: len(list(group)) for key, group in groupby(sorted(my_list))}           

說明:groupby函數會将相鄰相同元素分到一個組中,是以先用sorted函數排序就是為了将相同的元素放到一起。

from collections import Counterdict(Counter(my_list))           

截斷清單元素

假設清單對象對應的變量名為my_list,通常大家會想到用下面的方式來截斷清單。

my_list = my_list[:i]my_list = my_list[j:]           

然而,更好的方式使用下面的操作,大家可以認真想想為什麼。

del my_list[i:]del my_list[:j]           

按最長清單實作zip操作

Python的内置函數zip可以産生一個生成器對象,該生成器對象将兩個或多個可疊代對象的元素組裝到一起,如下所示。

 list(zip('abc', [1, 2, 3, 4]))           

執行上面的代碼會得到一個如下所示的清單,相信大家也注意到了,清單中元素的個數是由zip函數中長度最小的可疊代對象決定的,是以下面的清單中隻有3個元素。

 [('a', 1), ('b', 2), ('c', 3)]           

如果希望由zip函數中長度最大的可疊代對象來決定最終疊代出的元素個數,可以試一試itertools子產品的zip_longest函數,其用法如下所示。

  from itertools import zip_longestlist(zip_longest('abc', [1, 2, 3, 4]))           

上面的代碼建立出的清單對象如下所示。

  [('a', 1), ('b', 2), ('c', 3), (None, 4)]           

快速拷貝一個清單

如果希望快速拷貝一個清單對象,可以通過切片操作來實作,但是切片操作僅實作了淺拷貝,簡單的說就是切片建立了新的清單對象,但是新清單中的元素是和之前的清單共享的。如果希望實作深拷貝,可以使用copy子產品的deepcopy函數。

淺拷貝

thy_list = my_list[:]           

 import copythy_list = copy.copy(my_list)           

深拷貝

import copythy_list = copy.deepcopy(my_list)           

對兩個或多個清單對應元素進行操作

Python内置函數中的map函數可以對一個可疊代對象中的元素進行“映射”操作,這個函數在批量處理資料時非常有用。但是很多人都不知道,這個函數還可以作用于多個可疊代對象,通過傳入的函數對多個可疊代對象中的對應元素進行處理,如下所示:

my_list = [11, 13, 15, 17]thy_list = [2, 4, 6, 8, 10]list(map(lambda x, y: x + y, my_list, thy_list))           

上面的操作會得到如下所示的清單。

 [13, 17, 21, 25]           

當然,同樣的操作也可以用zip函數配合清單生成式來完成。

 my_list = [11, 13, 15, 17]thy_list = [2, 4, 6, 8, 10][x + y for x, y in zip(my_list, thy_list)]           

處理清單中的空值和零值

假設清單對象對應的變量名為my_list,如果清單中有空值(None)和零值,我們可以用下面的方式去掉空值和零值。

 list(filter(bool, my_list))           

對應的清單生成式文法如下所示。

 [x for x in my_list if x]           

從嵌套清單中抽取指定列

假設my_list是一個如下所示的嵌套清單,該嵌套清單可以用來表示數學上的矩陣,如果要取出矩陣第一列的元素構成一個清單,我們可以這樣寫。

 my_list = [
      [1, 1, 2, 2],
      [5, 6, 7, 8],
      [3, 3, 4, 4],]col1, *_ = zip(*my_list)list(col1)           

這裡我們會得到一個如下所示的清單,剛好是矩陣的第一列。

[1, 5, 3]           

以此類推,如果想取出矩陣第二列的元素構成一個清單,可以用如下所示的方法。

 _, col2, *_ = zip(*my_list)list(col2)           

至此,如果要實作矩陣的轉置操作,我們也可以按照上面的思路寫出下面的代碼。 

[list(x) for x in zip(*my_list)]           

經過上面的操作,我們會得到如下所示的清單。

  [[1, 5, 3], 
   [1, 6, 3], 
   [2, 7, 4], 
   [2, 8, 4]]