iT邦幫忙

5

超實用的python小技巧

常常要用python做一件看起來很簡單的事,
卻不小心寫的很複雜?
本文嘗試收集開發python程式常用的小技巧,
方便查詢使用

使用須知:
為了將程式寫的精簡,
有時語法不是那麼易懂,
所以建議可以將功能包裝成函數增加可讀性

目錄:
這邊將文章收錄的功能整理出來,
可在此瀏覽是否有你想找的

<容器類>(list, set, dict, ...)

  • 查詢一個元素是否在list中
  • 去除列表中重複的元素,需保持列表元素原來的順序
  • 合併多個字典,若key值相同新的會覆蓋舊的
  • 給定一個整數陣列,回傳每個位置元素的排名(最小為1)
  • 將嵌套list拉平成一維
  • 將一個列表k個元素分成一組,變成兩維列表
  • 將兩個list組合成dict
  • dict的key-value互換

<實用內建函數類>

  • 計算每個元素出現次數

容器類(list, set, dict, ...)

查詢一個元素是否在list中

範例input: 
List = [30,23,'a',6,97]
target = 6
範例output: True

說明: 程式很簡單,但是你若一開始學其它程式語言而轉換到python的話,
邏輯很容易寫成用for迴圈檢查每個元素是否等於目標值,
其實python有in運算子,可讀性高又簡潔

程式:

def BAD_find_in(List, target):
    for e in List:
        if e==target:
            return True
    return False

def find_in(List, target):
    return target in List
    
List = [30,23,'a',6,97]
target = 6
print(find_in(List, target)) # True

去除列表中重複的元素,需保持列表元素原來的順序

範例input: ["a", "b", "a", "c", "c"]
範例output: ["a", "b", "c"]

程式:

def removeDuplicate(arr):
    """
    自python3.6版以後,
    亦可寫 return list(dict.fromkeys(arr))
    因為python3.6版以後的字典是有序的(3.6版前的字典無序就會錯)
    """
    return sorted(set(arr), key = arr.index)

mylist = removeDuplicate(["a", "b", "a", "c", "c"])
print(mylist) #["a", "b", "c"]

合併多個字典,若key值相同新的會覆蓋舊的

範例input: 
x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = {'e': 10}
範例output: {'a': 1, 'b': 3, 'c': 4, 'e': 10}

程式:

def merge_dicts(*dict_args):
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}
z = {'e': 10}
print(merge_dicts(x,y,z))

給定一個整數陣列,回傳每個位置元素的排名(最小為1)

範例input: [1,1,2,5,-6,0,2]
範例output: [3, 3, 4, 5, 1, 2, 4]

說明: 原陣列由小到大排序為[-6, 0, 1, 2, 5],
第一個元素1第三小,
第二個元素1第三小,
第三個元素2第四小,

程式:

def get_rank(X):
    x_rank = dict((x, i+1) for i, x in enumerate(sorted(set(X))))
    return [x_rank[x] for x in X]

print(get_rank([1,1,2,5,-6,0,2]))

將嵌套list拉平成一維

範例input: [[1,2,3],[4,5],[6,7]]
範例output: [1, 2, 3, 4, 5, 6, 7]

程式:

#最簡單的攤平列表的方法,適用普通的二維列表
def singleFlat(arr):
    return sum(arr, [])

# 將一個多重嵌套的list轉為一維list,一行解 (是容器就拆,否則成list)
def flat(arr):
    return [x for sub in arr for x in flat(sub)] if isinstance(arr, (list,tuple,set,dict)) else [arr]

L=[{1,2},{1:'A'},(1,"H",3),[5,[2,1],(3,4)],50,(1,['54',0])]
print(flat(L))

將一個列表k個元素分成一組,變成兩維列表

範例input: 
List = [1,2,3,4,5,6,7,8,9,10,11,20,66]
step = 3
範例output: 
(正常分組)[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 20], [66]]
(從尾端分組)[[1], [2, 3, 4], [5, 6, 7], [8, 9, 10], [11, 20, 66]]

程式:

def sepList(L,step):
    return [L[i:i+step] for i in range(0,len(L),step)]

#從後面分組
def backSepList(L,step):
    return [L[max(0,i-step+1):i+1] for i in range(len(L)-1,-1,-step)][::-1]
    # <另解> return list(map(lambda x: list(reversed(x)),sepList(L[::-1],step)))[::-1]

a = [1,2,3,4,5,6,7,8,9,10,11,20,66]
step = 3
print(sepList(a,step)) #[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 20], [66]]
print(backSepList(a,step)) #[[1], [2, 3, 4], [5, 6, 7], [8, 9, 10], [11, 20, 66]]

將兩個list組合成dict

範例input: ['A', 'B', 'C'], [1, 2, 3]
範例output: {'A': 1, 'B': 2, 'C': 3}

程式:

def mergeListToDict(list1, list2):
    return dict(zip(list1, list2))

A = ['A', 'B', 'C']
B = [1, 2, 3]
print(mergeListToDict(A,B))

dict的key-value互換(需要是一對一的關係)

範例input: {'a': 1, 'b': 2, 'c': 3, 'd': 4}
範例output: {1: 'a', 2: 'b', 3: 'c', 4: 'd'}

程式:

def dict_key_val_reverse(D):
    # 將字典的鍵-值互換,例: {'a': 1, 'b': 2}-> {1: 'a', 2: 'b'}
    return dict(zip(D.values(), D.keys())) #另解: return {v: k for k, v in m.items()}

實用內建函數類

計算每個元素出現次數

範例input: myList = ['A','B','A','A','B','B','A','C','C','C']
範例output: Counter({'A': 4, 'B': 3, 'C': 3})

程式:

from collections import Counter
myList = ['A','B','A','A','B','B','A','C','C','C']
count = Counter(myList)
print(count) # Counter({'A': 4, 'B': 3, 'C': 3})
print(count['A']) # 4 
print(count['D']) #對於不存在的值默認為0
print(count.most_common(2)) #出現次數最高的兩個元素: [('A', 4), ('B', 3)]

尚未有邦友留言

立即登入留言