True/False判定
False | True |
---|---|
False | True (== 1) |
0, 0.0 | 非0数值 |
(), [], {}, set() | 含有元素的容器 |
None |
在进行判断的时候直接根据上表进行判断,
if x:
...
避免进行类似判断,
if x == True:
...
if x is not None and len(x) > 0:
...
但是在某些情况下如果要再进一步区分就需要显示指定,
if x is None:
...
elif len(x) == 0:
...
else:
...
字符串
字符串拼接
合理选择%,format方法。format方法支持更多特性,适用更多场景。
# 格式化参数较少,通过字符串格式化进行拼接
msg = 'hello %s' % name
# 格式化参数较多,且当前context存在包含格式化参数的dict,
msg = 'today is %{today}s, tommorow is %{tomorrow}s' % {'today': today, 'tomorrow': tomorrow}
# 格式化参数较多,且当前context不存在包含格式化参数的dict,通过字符串format函数进行拼接
msg = 'today is %{today}s, tommorow is %{tomorrow}s'.format(today=today, tomorrow=tomorrow)
从列表构建字符串
numbers = [1, 2, 3, 4, 5]
# 用,分割
result = ','.join(numbers)
# 用,分割,且对列表中数字进行处理
result = ','.join(x*x for x in numbers)
长字符串定义
推荐将字符串定义在()内,让Python自动进行字符串拼接
# 'foobar'
result = ('foo'
'bar')
容器
list
- 通过enumerate访问下标及元素
colors = ['red', 'green', 'blue']
for idx, color in enumerate(colors):
print idx, color
- 使用xrange而不是range,range会返回list,xrange返回xrange object
for i in xrange(100):
...
- 优先使用list comprehension而不是map
numbers = [1, 2, 3, 4, 5]
numbers = [x * x for x in numbers]
numbers = map(lambda x: x * x, numbers)
set
- 有默认元素时可用{}进行初始化
empty_set = set()
color_set = {'red', 'green', 'blue'}
dict
- 判断元素是否在容器中,使用in,而不是has_key
'A' in char_dict
- 使用collections.defaultdict给dict设置默认值
from collections import defaultdict
words = defaultdict(list)
words['en'].append('a')
函数
- 避免函数默认参数使用可变容器,默认参数只会创建一次,多次进入函数会实际会获取到不同的默认值
def foo(values=[]):
...
values.append('a')
...
generator
- 定义generator,返回数据时使用yield
def reverse(data):
for index in xrange(len(data)-1, -1, -1):
yield data[index]
- 适当使用generator,在不需要创建list保存数据时可以使用generator expression
numbers = [1, 2, 3, 4, 5]
# list comprehension
sum = sum([x * x for x in numbers])
# generator
sum = sum(x * x for x in numbers)
decorator
-
staticmethod, classmethod, module function使用
- 如果一组函数可以被归类或归组,则推荐使用staticmethod定义在类中
- 如果函数需要访问类对象,则推荐使用classmethod
- 其它情况下再可考虑直接定义成module function
-
记录函数运行时间
import time
def tracker(func):
def _tracker(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print 'func %s cost %s' % (func.__name__, time.time() - start)
return result
@tracker
def foo():
pass
- 强制验证参数类型
- 缓存函数操作结果
- 其它公共统一逻辑处理
排序
- 对列表进行默认排序
numbers = [2, 1, 3, 5, 4]
# 在list上直接进行修改
numbers.sort()
# 不改变原数据,返回新列表
sorted(numbers)
- 指定排序函数
items = [('A', 1), ('B', 11), ('B', 10)]
# 按item第2个元素进行排序
items.sort(key=lambda x: x[1])
- 根据多个元素进行排序,使用operator.itemgetter
items = [('A', 1), ('B', 11), ('B', 10), ('A', 0)]
# 先比较第一个元素,再比较第二个元素,利用了tuple比较规则
items.sort(key=itemgetter(0, 1))
- 更复杂的排序比较条件可以通过定义更复杂的key function来进行处理
class K(object):
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return self.obj < other
def __gt__(self, other):
return self.obj > other
def __ne__(self, other):
return self.obj != other
numbers = [2, 1, 3, 5, 4]
sorted(numbers, key=K)
- 或者可以自定cmp函数,并通过functools.cmp_to_key转化成key function,
from functools import cmp_to_key
def cmp(x, y):
return x - y
numbers = [2, 1, 3, 5, 4]
sorted(numbers, key=cmp_to_key(cmp))
其它
- 行末注意不要添加多余逗号,否则会无意识下使得变量类型别成tuple,导致后续逻辑运行时异常
# name is num
num = 100
# name is tuple
num = 100,
- 需要明确判断变量是否为None时用is,
if val is None:
...
if val is not None:
...
- 用is进行identity判断,==进行equality判断
a = 'foobar'
b = ''.join(('foo', 'bar'))
# True
a == b
# False
a is b
- 除法 //,省略掉小数部分
# 0
3 // 2
# 1.0
3.3 // 2
- 定义singleton
class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
- 类型检查用isinstance,但实际编码中最好不要一类类型检查,在继承关系当中最好通过overridde is_xxx()系列函数来进行判断
Reference
- Expert Python Programming
- Code Like a Pythonista: Idiomatic Python
- The Hitchhiker’s Guide to Python
- Sorting Mini-HOW TO