筆記 Pythonic Style Coding,藉由風格對比的方式,深化至自己的心中。
說明
- Using List Comprehension
- Unpythonic 😥
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n ** 2)
- Pythonic 😎
numbers = [1, 2, 3, 4, 5]
squares = [n ** 2 for n in numbers]
- Iterating Over Dictionary Items
- Unpythonic 😥
dictionary = {'a': 1, 'b': 2, 'c': 3}
for key in dictionary.keys():
print(key, dictionary[key])
- Pythonic 😎
dictionary = {'a': 1, 'b': 2, 'c': 3}
for key, value in dictionary.items():
print(key, value)
- File Operations :
with
- Unpythonic 😥
file = open('file.txt', 'r')
content = file.read()
print(content)
file.close()
- Pythonic 😎
with open('file.txt', 'r') as file:
content = file.read()
print(content)
- Swapping Variable Values
- Unpythonic 😥
a = 1
b = 2
temp = a
a = b
b = temp
- Pythonic 😎
a = 1
b = 2
a, b = b, a
- Conditional Expressions
- Unpythonic 😥
if condition:
x = 1
else:
x = 0
- Pythonic 😎
x = 1 if condition else 0
- 使用 enumerate (Using enumerate)
- Unpythonic 😥
my_list = ['apple', 'banana', 'grape']
i = 0
for item in my_list:
print(i, item)
i += 1
- Pythonic 😎
my_list = ['apple', 'banana', 'grape']
for i, item in enumerate(my_list):
print(i, item)
- Using the Zip Function
- Unpythonic 😥
keys = ['a', 'b', 'c']
values = [1, 2, 3]
my_dict = {}
for i in range(len(keys)):
my_dict[keys[i]] = values[i]
- Pythonic 😎
keys = ['a', 'b', 'c']
values = [1, 2, 3]
my_dict = dict(zip(keys, values))
- Defining Default Values in Functions
- Unpythonic 😥
def foo(bar):
if bar is None:
bar = []
# do something with bar
- Pythonic 😎
def foo(bar = None):
bar = bar or []
# do something with bar
- Using Generator Expressions
- Unpythonic 😥
numbers = [1, 2, 3, 4, 5]
sum_squares = sum([n ** 2 for n in numbers])
- Pythonic 😎
numbers = [1, 2, 3, 4, 5]
sum_squares = sum(n ** 2 for n in numbers)
- Using
*args
and**kwargs
- Unpythonic 😥
def foo(a, b, c, d):
print(a, b, c, d)
foo(1, 2, 3, 4)
- Pythonic 😎
def foo(*args, **kwargs):
print(*args, **kwargs)
foo(1, 2, c=3, d=4)
- String Concatenation
- Unpythonic 😥
strings = ['Hello', 'World']
result = ''
for s in strings:
result += s
- Pythonic 😎
strings = ['Hello', 'World']
result = ''.join(strings)
- Filtering Lists with Comprehension
- Unpythonic 😥
numbers = [1, 2, 3, 4, 5, 6]
even = []
for n in numbers:
if n % 2 == 0:
even.append(n)
- Pythonic 😎
numbers = [1, 2, 3, 4, 5, 6]
even = [n for n in numbers if n % 2 == 0]
- Multiple Return Values
- Unpythonic 😥
def get_user():
# ... some logic ...
return name, age, email
result = get_user()
name = result[0]
age = result[1]
email = result[2]
- Pythonic 😎
def get_user():
# ... some logic ...
return name, age, email
name, age, email = get_user()
- sing List’s extend Method
- Unpythonic 😥
list1 = [1, 2, 3]
list2 = [4, 5, 6]
for item in list2:
list1.append(item)
- Pythonic 😎
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list1.extend(list2)
- 字典預設值 (Dictionary Default Values)
- Unpythonic 😥
dict = {'a': 1, 'b': 2}
if 'c' in dict:
value = dict['c']
else:
value = 'default'
- Pythonic 😎
dict = {'a': 1, 'b': 2}
value = dict.get('c', 'default')
- List Slicing
- Unpythonic 😥
my_list = [1, 2, 3, 4, 5]
first_three = []
for i in range(3):
first_three.append(my_list[i])
- Pythonic 😎
my_list = [1, 2, 3, 4, 5]
first_three = my_list[:3]
- Using map and filter
- Unpythonic 😥
numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
squares.append(n ** 2)
even_squares = []
for square in squares:
if square % 2 == 0:
even_squares.append(square)
- Pythonic 😎
numbers = [1, 2, 3, 4, 5]
even_squares = map(lambda n: n ** 2, filter(lambda n: n % 2 == 0, numbers))
- Using all or any
- Unpythonic 😥
values = [True, True, False]
all_true = True
for v in values:
if not v:
all_true = False
break
- Pythonic 😎
values = [True, True, False]
all_true = all(values)
- Using Sets to Remove Duplicates
- Unpythonic 😥
my_list = [1, 2, 2, 3, 3, 3]
unique_list = []
for item in my_list:
if item not in unique_list:
unique_list.append(item)
- Pythonic 😎
my_list = [1, 2, 2, 3, 3, 3]
unique_list = list(set(my_list))
- Concise Function Definition
- Unpythonic 😥
def square(x):
return x * x
- Pythonic 😎
square = lambda x: x * x
- Merging Dictionaries
- Unpythonic 😥
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged = dict1.copy()
for key in dict2:
merged[key] = dict2[key]
- Pythonic 😎
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged = {**dict1, **dict2}
- Reversing Lists
- Unpythonic 😥
my_list = [1, 2, 3, 4, 5]
reversed_list = []
for item in reversed(my_list):
reversed_list.append(item)
- Pythonic 😎
my_list = [1, 2, 3, 4, 5]
reversed_list = my_list[::-1]
- Set Operations
- Unpythonic 😥
set1 = {1, 2, 3}
set2 = {3, 4, 5}
intersection = set()
for item in set1:
if item in set2:
intersection.add(item)
- Pythonic 😎
set1 = {1, 2, 3}
set2 = {3, 4, 5}
intersection = set1 & set2
同場加映 🎬
union = set1 | set2
difference = set1 - set2
symmetric_difference = set1 ^ set2
is_subset = set1 <= set2
is_superset = set1 >= set2
is_disjoint = set1.isdisjoint(set2)
- 使用 defaultdict (Using defaultdict)
- Unpythonic 😥
my_dict = {}
for key, value in pairs:
if key not in my_dict:
my_dict[key] = []
my_dict[key].append(value)
- Pythonic 😎
from collections import defaultdict
my_dict = defaultdict(list)
for key, value in pairs:
my_dict[key].append(value)
- Logging Function Execution Time
- Unpythonic 😥
import time
def my_function():
start_time = time.time()
# function logic
end_time = time.time()
print(f"Time taken: {end_time - start_time} seconds")
- Pythonic 😎
import time
import functools
def timer(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
value = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} took {end_time - start_time} seconds")
return value
return wrapper
@timer
def my_function():
# function logic
- 鏈式比較 (Chained Comparisons)
- Unpythonic 😥
if x > 5 and x < 10:
pass
- Pythonic 😎
if 5 < x < 10:
pass
- 使用
reversed
函数 (Usingreversed
)
- Unpythonic 😥
for i in range(len(my_list) - 1, -1, -1):
print(my_list[i])
- Pythonic 😎
for item in reversed(my_list):
print(item)
- 字典推導式(Dictionary Comprehension)
- Unpythonic 😥
keys = ['a', 'b', 'c']
values = [1, 2, 3]
my_dict = {}
for i in range(len(keys)):
my_dict[keys[i]] = values[i]
- Pythonic 😎
keys = ['a', 'b', 'c']
values = [1, 2, 3]
my_dict = {k: v for k, v in zip(keys, values)}
- 同時獲取索引和值(Getting Index and Value Simultaneously)
- Unpythonic 😥
my_list = ['a', 'b', 'c']
for i in range(len(my_list)):
print(i, my_list[i])
- Pythonic 😎
my_list = ['a', 'b', 'c']
for index, value in enumerate(my_list):
print(index, value)
- 使用生成器表達式(Using Generator Expressions)
- Unpythonic 😥
def square_numbers(nums):
for num in nums:
yield num * num
- Pythonic 😎
nums = [1, 2, 3, 4]
square_gen = (num * num for num in nums)
- 函數參數解包 (Function Parameter Unpacking)
- Unpythonic 😥
def my_func(a, b, c):
print(a, b, c)
args = [1, 2, 3]
my_func(args[0], args[1], args[2])
- Pythonic 😎
args = [1, 2, 3]
my_func(*args)
- 使用
itertools.chain
合并迭代器 (Using itertools.chain)
- Unpythonic 😥
list1 = [1, 2, 3]
list2 = [4, 5, 6]
for list in (list1, list2):
for item in list:
process(item)
- Pythonic 😎
import itertools
list1 = [1, 2, 3]
list2 = [4, 5, 6]
for item in itertools.chain(list1, list2):
process(item)
- 使用
_
忽略特定值 (Using _ to Ignore Specific Values)
- Unpythonic 😥
a, b, c = (1, 2, 3)
print(a, b)
- Pythonic 😎
a, b, _ = (1, 2, 3)
print(a, b)
- 使用
:=
賦值表達式(自 Python 3.8 起) (Using := Assignment Expression)
- Unpythonic 😥
n = len(my_list)
if n > 4:
print(f"List is too long ({n} elements, expected <= 4)")
- Pythonic 😎
if (n := len(my_list)) > 4:
print(f"List is too long ({n} elements, expected <= 4)")
- 使用
pathlib
處理路徑 (Using pathlib for Path Handling)
- Unpythonic 😥
import os
filepath = os.path.join('dir', 'file.txt')
- 語法糖寫法(使用
pathlib
):
from pathlib import Path
filepath = Path('dir') / 'file.txt'
- 使用
or
簡化賦值 (Simplifying Assignment with or)
- Unpythonic 😥
name = ''
if user_name:
name = user_name
else:
name = 'Guest'
- Pythonic 😎
name = user_name or 'Guest'
- Using Set Comprehension
- Unpythonic 😥
my_list = [1, 2, 2, 3, 3, 3]
my_set = set()
for item in my_list:
my_set.add(item)
- Pythonic 😎
my_list = [1, 2, 2, 3, 3, 3]
my_set = {item for item in my_list}
- Using f-string
- Unpythonic 😥
name = "Alice"
greeting = "Hello, " + name + "!"
- Pythonic 😎
name = "Alice"
greeting = f"Hello, {name}!"
- 以優雅方式進行異常處理 (Concise Exception Handling)
- Unpythonic 😥
try:
result = 10 / number
except ZeroDivisionError:
result = "Infinity"
- Pythonic 😎
result = 10 / number if number else "Infinity"
- 使用
itertools
(Using itertools)
- Unpythonic 😥
pairs = []
for a in range(3):
for b in range(3):
if a != b:
pairs.append((a, b))
- Pythonic 😎
import itertools
pairs = [(a, b) for a, b in itertools.permutations(range(3), 2)]
- 使用
functools.reduce
(Usingfunctools.reduce
)
- Unpythonic 😥
numbers = [1, 2, 3, 4]
result = 0
for num in numbers:
result += num
- Pythonic 😎
from functools import reduce
numbers = [1, 2, 3, 4]
result = reduce(lambda x, y: x + y, numbers)
- 使用
next
與迭代器 (Usingnext
with Iterators)
- Unpythonic 😥
for item in my_iterable:
first_item = item
break
- Pythonic 😎
first_item = next(iter(my_iterable))
- Using List’s
pop
- Unpythonic 😥
last_item = my_list[len(my_list) - 1]
my_list = my_list[:-1]
- Pythonic 😎
last_item = my_list.pop()
- 迴圈中使用
else
(Usingelse
in Loops)
- Unpythonic 😥
found = False
for item in my_list:
if condition(item):
process(item)
found = True
break
if not found:
handle_not_found()
- Pythonic 😎
for item in my_list:
if condition(item):
process(item)
break
else:
handle_not_found()
- 使用
contextlib.suppress
(Usingcontextlib.suppress
)
- Unpythonic 😥
try:
os.remove(filename)
except FileNotFoundError:
pass
- Pythonic 😎
from contextlib import suppress
with suppress(FileNotFoundError):
os.remove(filename)
- Optimizing Code with Assignment Expressions
- Unpythonic 😥
file = open('test.txt')
data = file.readline()
while data:
process(data)
data = file.readline()
- Pythonic 😎
with open('test.txt') as file:
while (data := file.readline()):
process(data)
- Using List’s
clear
Method
- Unpythonic 😥
my_list = [1, 2, 3, 4, 5]
del my_list[:]
- Pythonic 😎
my_list = [1, 2, 3, 4, 5]
my_list.clear()
- Using
zip
to Iterate Over Multiple Sequences Simultaneously
- Unpythonic 😥
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for i in range(len(list1)):
print(list1[i], list2[i])
- Pythonic 😎
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
for number, letter in zip(list1, list2):
print(number, letter)
- 使用
divmod
函數 (Usingdivmod
Function)
- Unpythonic 😥
dividend, divisor = 20, 7
quotient = dividend // divisor
remainder = dividend % divisor
- Pythonic 😎
dividend, divisor = 20, 7
quotient, remainder = divmod(dividend, divisor)
- 條件判斷 (Optimizing Conditional Statements)
- Unpythonic 😥
if x == 'a' or x == 'b' or x == 'c':
pass
- Pythonic 😎
if x in ('a', 'b', 'c'):
pass
- 多重賦值 (Optimizing Multiple Assignments)
- Unpythonic 😥
x = 5
y = 5
z = 5
- Pythonic 😎
x = y = z = 5
- Membership Check with
in
- Unpythonic 😥
if my_list.count(x) > 0:
pass
- Pythonic 😎
if x in my_list:
pass
- Using
collections.Counter
for Element Counting
- Unpythonic 😥
my_list = ['a', 'b', 'c', 'a', 'b', 'b']
count = {}
for item in my_list:
if item in count:
count[item] += 1
else:
count[item] = 1
- Pythonic 😎
from collections import Counter
my_list = ['a', 'b', 'c', 'a', 'b', 'b']
count = Counter(my_list)