python一些常用小技巧

  • 2019 年 12 月 17 日
  • 筆記

最近看到我關注的某公眾號,文章是從網上原封不動的抄的,隨便一搜,網路上都是那個文章。這個還不是重點,重點是,程式碼里有很多錯誤,而且是用截圖方式弄的,別人想借鑒,還不能copy. 我重新整理了一下,並且在自己機器上運行通過,也算是自己鞏固,然後正本清源吧!

  1. 分塊

給定具體的大小,定義一個函數以按照這個大小切割列表。

from math import ceil  def chunk(lst, size):      return list( map(lambda x: lst[x * size:x * size + size], list(range(0, ceil(len(lst) / size)))))  print(chunk([1,2,3,4,5],2))# [[1,2],[3,4],5]
  1. 壓縮

這個方法可以將布爾型的值去掉,例如(False,None,0,「」),它使用 filter() 函數。

def compact(lst):      return list(filter(bool, lst))  print(compact([0, 1, False, 2, '', 3, 'a', 's', 34]))# [ 1, 2, 3, 'a', 's', 34 ]
  1. 解包

如下程式碼段可以將打包好的成對列表解開成兩組不同的元組。

array = [['a', 'b'], ['c', 'd'], ['e', 'f']]  transposed = list(zip(*array))  print(transposed)# [('a', 'c', 'e'), ('b', 'd', 'f')]  print(*transposed) # ('a', 'c', 'e') ('b', 'd', 'f')
  1. 逗號連接

下面的程式碼可以將列`表連接成單個字元串,且每一個元素間的分隔方式設置為了逗號。

hobbies = ["basketball", "football", "swimming"]  print("My hobbies are: " + ", ".join(hobbies))  # My hobbies are: basketball, football, swimming
  1. 列表的差

該方法將返回第一個列表的元素,其不在第二個列表內。如果同時要回饋第二個列表獨有的元素,還需要加一 set_b.difference(set_a).

def difference(a, b):      set_a = set(a)      set_b = set(b)      comparison = set_a.difference(set_b)      return list(comparison)  print(difference([1,2,3], [1,2,4])) # [3]
  1. 通過函數取差

如下方法首先會應用一個給定的函數,然後再返回應用函數後結果有差別的列表元素。

from math import floor  def difference_by(a, b, fn):      b = set(map(fn, b))      return [item for item in a if fn(item) not in b]    print(difference_by([2.1, 1.2], [2.3, 3.4],floor)) # [1.2]
  1. 獲取當前路徑下的文件:
import os    print(os.getcwd())    my_file = [d for d in os.listdir(".")]  print(my_file)
  1. 獲取執行文件的文件名和路徑:
  import os  #__file__是當前執行的文件  # 獲取當前文件__file__的路徑  print("os.path.realpath(__file__)={}".format(os.path.realpath(__file__)))    # 獲取當前文件__file__的所在目錄    print(os.path.dirname(os.path.realpath(__file__)))  # 獲取當前文件__file__的所在目錄    print(os.path.split(os.path.realpath(__file__))[0])
  1. 獲取某個目錄下所有的文件名和目錄名:
for d in os.listdir(os.path.split(os.path.realpath(__file__))[0]):      print(d)

如果需要深層的,則需要遞歸了,並且判斷 isfile(), isdir()

10. 字元串反轉

切片操作來反轉字元串:

# Reversing a string using slicing    my_string = "ABCDE"  reversed_string = my_string[::-1]    print(reversed_string)    # Output  # EDCBA
  1. 大寫每個首字母 Python capitalize()將字元串的第一個字母變成大寫,其他字母變小寫,通過方法 title() 實現每個單詞首字母大寫:
my_string = "my name is chaitanya baweja"    # using the title() function of string class  new_string = my_string.title()    print(new_string)    # Output  # My Name Is Chaitanya Baweja
  1. 字元串去重 最簡單的是通過集合 set 來實現:
my_string = "aavvccccddddeee"    # converting the string to a set  temp_set = set(my_string)    # stitching set into a string using join  new_string = ''.join(temp_set)    print(new_string)
  1. 字元串的重複,乘以N就可以了
n = 3 # number of repetitions    my_string = "abcd"  my_list = [1,2,3]    print(my_string*n)  # abcdabcdabcd    print(my_string*n)  # [1,2,3,1,2,3,1,2,3]

列表元素也可以

n = 4  my_list = [0]*n  # [0, 0, 0, 0]
  1. 列表推導式
original_list = [1,2,3,4]    new_list = [2*x for x in original_list]    print(new_list)  # [2,4,6,8]
  1. 原地交換變數 交換兩個變數的數值是非常簡單的,完全不需要第三個變數作為中間值。
a = 1  b = 2    a, b = b, a    print(a) # 2  print(b) # 1
  1. 字元串分割 split()
string_1 = "My name is Chaitanya Baweja"  string_2 = "sample/ string 2"    # 默認分割符 ' '  print(string_1.split())  # ['My', 'name', 'is', 'Chaitanya', 'Baweja']    # 自定義分割符 '/'  print(string_2.split('/'))  # ['sample', ' string 2']
  1. 字元串合併 join()
list_of_strings = ['My', 'name', 'is', 'Chaitanya', 'Baweja']    # Using join with the comma separator  print(','.join(list_of_strings))    # Output  # My,name,is,Chaitanya,Baweja
  1. 判斷字元串是否迴文 通過反轉字元串,再和原字元串比較
my_string = "abcba"    if my_string == my_string[::-1]:      print("palindrome")  else:      print("not palindrome")    # Output  # palindrome
  1. 統計列表元素的個數 有多種方式可以實現這個技巧,但我最喜歡的是採用 Counter 類。

Counter可以統計給定列表中每個元素的個數,其中 most_common()可以返回列表數量最多的元素

# finding frequency of each element in a list  from collections import Counter    my_list = ['a','a','b','b','b','c','d','d','d','d','d']  count = Counter(my_list) # defining a counter object    print(count) # Of all elements  # Counter({'d': 5, 'b': 3, 'a': 2, 'c': 1})    print(count['b']) # of individual element  # 3    print(count.most_common(1)) # most frequent element  # [('d', 5)]
  1. 判斷兩個字元串是否是字謎(Anagrams) 字謎(Anagrams)是指將一個單詞打亂其字母順序,重新排列為一個新的單詞。

Counter正好可以用於解決這個問題,因為包含相同元素且元素數量都相同。

示例如下:

from collections import Counter    str_1, str_2, str_3 = "acbde", "abced", "abcda"  cnt_1, cnt_2, cnt_3  = Counter(str_1), Counter(str_2), Counter(str_3)    if cnt_1 == cnt_2:      print('1 and 2 anagram')  if cnt_1 == cnt_3:      print('1 and 3 anagram')
  1. 採用 try-except-else 語句 Python 中處理錯誤異常可以簡單採用 try-except 語句,而再添加一個 else 語句會更加有幫助,它是在沒有發生異常時,執行完 try 語句後運行的語句。

此外,如果需要運行是否發現異常的都需要執行的程式碼,可以採用 finally ,

a, b = 1,0    try:      print(a/b)      # exception raised when b is 0  except ZeroDivisionError:      print("division by zero")  else:      print("no exceptions raised")  finally:      print("Run this always")
  1. 用Enumerate獲取索引值 在迭代列表的時候,可用 enumerate 來得到索引值,
my_list = ['a', 'b', 'c', 'd', 'e']    for index, value in enumerate(my_list):      print('{0}: {1}'.format(index, value))    # 0: a  # 1: b  # 2: c  # 3: d  # 4: e

注意,這裡還可以指定索引開始的範圍,添加一個參數

my_list = ['a', 'b', 'c', 'd', 'e']    for index, value in enumerate(my_list, 1):      print('{0}: {1}'.format(index, value))
  1. 檢查一個對象的記憶體使用量 可用 sys.getsizeof() 檢查,示例如下:
import sys    num = 21    print(sys.getsizeof(num))    # In Python 2, 24  # In Python 3, 28
  1. 合併兩個字典 在 Python2 版本可用 update() 方法實現合併字典,但在 Python3.5 後的版本,可以採用新的方式實現,操作更加簡單
dict_1 = {'apple': 9, 'banana': 6}  dict_2 = {'banana': 4, 'orange': 8}    combined_dict = {**dict_1, **dict_2}    print(combined_dict)  # Output  # {'apple': 9, 'banana': 4, 'orange': 8}
  1. 計算程式碼執行時間 採用time模組來計算一段程式碼的執行時間
import time    start_time = time.time()  # Code to check follows  a, b = 1,2  c = a+ b  # Code to check ends  end_time = time.time()  time_taken_in_micro = (end_time- start_time)*(10**6)    print(" Time taken in micro_seconds: {0} ms").format(time_taken_in_micro)
  1. 展開元素為列表的列表 有時候並確定一個列表中的深度有多深,所以你只想簡單的將所有元素都放在一個列表中
from iteration_utilities import deepflatten    # 列表只有一層深度的情況,採用這個函數  def flatten(l):    return [item for sublist in l for item in sublist]    l = [[1,2,3],[3]]  print(flatten(l))  # [1, 2, 3, 3]    # 不知道列表的深度的情況  l = [[1,2,3],[4,[5],[6,7]],[8,[9,[10]]]]    print(list(deepflatten(l, depth=3)))  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  1. 從列表中取樣 採用 random 模組可以對一個列表隨機取樣 n 個元素,
import random    my_list = ['a', 'b', 'c', 'd', 'e']  num_samples = 2    samples = random.sample(my_list,num_samples)  print(samples)  # [ 'a', 'e'] this will have any 2 random values

另外,在 Python 3 中推薦採用 secrets 模組

import secrets                              # imports secure module.  secure_random = secrets.SystemRandom()      # creates a secure random object.    my_list = ['a','b','c','d','e']  num_samples = 2    samples = secure_random.sample(my_list, num_samples)    print(samples)  # [ 'e', 'd'] this will have any 2 random values
  1. 檢查唯一性 下面的程式碼是用於判斷一個列表的所有元素是否都是唯一沒有重複的:
def unique(l):      if len(l)==len(set(l)):          print("All elements are unique")      else:          print("List has duplicates")    unique([1,2,3,4])  # All elements are unique    unique([1,1,2,3])  # List has duplicates

平時自己不斷積累,才會有所收穫,看到錯誤也能立即發現。