前言

刷題刷久了,有些東西一直重複手打,紀錄一些比較常用到的東西減緩手痛。
順便放一些不常用但很有用的奇怪小語法。
還有少數看過覺得很奇怪又幾乎不會用到的魔法。


常用小技巧

  1. 字串反轉、陣列反轉

    其實好像任何iterable的物件都可以這樣用。

     s1='123'
     s2=s1[::-1] # '321'
        
     a1=[1,2,3]
     a2=a1[::-1] # [3,2,1]
    
  2. 字串複製、陣列複製

    做backtracking常常用到,省了好多力。

     s1='1234'
     s2=s1[:] # '1234'
    
     a1=[1,2,3,4]
     a2=a1[:] # [1,2,3,4]
    
  3. 同時疊代索引及元素

    s=['a','b','c']
    for i,c in enumerate(s):
        print(i,c) # '0 a', '1 b', '2 c'
    
  4. 字串取子字串、陣列取子陣列

    左閉右開。取倒數第k個可以用-k。

     s1='1234'
     s2=s1[1:3] # '23'
    
     a1=[1,2,3,4]
     a2=a1[:1] # [1]
     a3=a1[-2:] # [3,4]
    
  5. 在集合中找符合條件的元素

    條件也可以很多個。

     # 在a中找可以被3整除的數
     a=[1,2,3,4,5,6,10,11,21,22]
     b=[x for x in a if x%3==0] # [3,6,21]
     c=[x for x in a if x%3==0 and x<10] # [3,6]
    
  6. 把二維陣列攤平

    很浪費記憶體,陣列太大容易爆炸。
    原理是sum()以第二個參數為初始值,以第一個參數中所有元素加總。

     mat=[[1,2,3],[4,5,6]]
     b=sum(mat,[]) # [1,2,3,4,5,6]
     # 下面這種比較有效率
     c=[x for r in mat for x in r] # [1,2,3,4,5,6]
    
  7. 遍歷英文字母、數字

    有時候手敲a~z真的快崩潰。

     # 'abcdefghijklmnopqrstuvwxyz'
     print(string.ascii_lowercase) 
     # 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
     print(string.ascii_uppercase) 
     # '0123456789'
     print(string.digits) 
    

不常用但是很有用小技巧

  1. 檢查字串s是否回文(palindromic)

     s1='abcd'
     s1==s1[::-1] # False
     s2='abba'
     s2==s2[::-1] # True
    
  2. 檢查字串s,t是否為異位構詞(anagram)

     s1='abcd'
     s2='abba'
     s3='baba'
     Counter(s1)==Counter(s2) # False
     Counter(s2)==Counter(s3) # True
    
  3. 在t中找子序列s

    來源StefanPochmann
    原理是in會持續到找到目標才停,若途中s的某個字元c找不到就是False。

     s='abs'
     t='ahbgdc'
     it = iter(t)
     all(c in it for c in s) # True
    
  4. 答案為0時回傳特定值

    ans=0
    print(ans or 'invalid') # 'invalid'
    
  5. 直接計算數學算式

    exp1='2*(2+3)'
    exp2='5-2'
    n1=eval(exp1) # 12
    n2=eval(exp2) # 3
    
  6. 字串格式化

    整數補0:
    %0長度d
    浮點數限制小數位:
    %.位數f

    year=2022
    month=4
    day=1
    print(f'{year}-{month}-{day}') # 2022-4-1
    print('%d-%02d-%02d') # 2022-04-01
    
  7. 除法向上取整

    被除數a 除數b
    向上取整=(a+b-1)/b

    up=10
    down=3
    ceil=up//down # 向上取整
    floor=(up+down-1)//down #向下取整
    print(ceil) # 4
    print(floor) # 3
    
  8. 找前k大/小的元素

    a=[1,2,3,4,5]
    large=heapq.nlargest(3,a)
    small=heapq.nsmallest(3,a)
    print(large) # [5,4,3]
    print(small) # [1,2,3]
    

很奇怪又幾乎不會用到的魔法

  1. 當集合正好剩下1個元素時,把它拿出來

    某次比賽看到人家用的,搞半天才弄懂這是什麼鬼。
    我寧願用pop()。

     s=set([1])
     x,=s
     print(x) # 1
    
  2. 用逗號生成tuple

    a=1,3,5
    print(a) # (1,3,5)
    
    b=[1,2]
    b+=4,
    print(b) # [1,2,4] 
    b+=5,6
    print(b) # [1,2,4,5,6]