Pythonic记录(转)
循环遍历可迭代对象(in enumerate)
- Non-Pythonic
# 基于索引的while循环
choices = ['red', 'green', 'blue']
i = 0
while i < len(choices):
print('{}) {}'.format(i, choices[i]))
i += 1
# 或者for循环:
choices = ['red', 'green', 'blue']
for i in range(len(choices)):
print('{}) {}'.format(i, choices[i]))
- Pythonic
choices = ['red', 'green', 'blue']
for choice in choices:
print(choice)
# 加上序列的枚举
choices = ['red', 'green', 'blue']
for idx, choice in enumerate(choices):
print('{}) {}'.format(idx, choice))
列表推导式
- Non-Pythonic
# 列表推导式
result = []
for i in range(10):
s = i 2
result.append(s)
- Pythonic
# 列表推导式
[i2 for i in xrange(10)]
漂亮的打印出JSON
>>> import json
>>> print(json.dumps(data)) # No indention
{"status": "OK", "count": 2, "results": [{"age": 27, "name": "Oz", "lactose_intolerant": true}, {"age": 29, "name": "Joe", "lactose_intolerant": false}]}
>>> print(json.dumps(data, indent=2)) # With indention
{
"status": "OK",
"count": 2,
"results": [
{
"age": 27,
"name": "Oz",
"lactose_intolerant": true
},
{
"age": 29,
"name": "Joe",
"lactose_intolerant": false
}
]
}
异常捕获代替if判断
- Non-Pythonic
if resource_exists():
use_resource()
- Pythonic
try:
use_resource()
except ResourceDoesNotExist:
...
优雅的字典操作
- Pythonic
# 读取键值,如果不存在不会抛出异常,直接返回Null
>>> dict().get('missing key', 'failover value')
'failover value'
# 设置默认值
>>> dict().setdefault('key', 'new value')
'new value'
>>> d = {'key': 'old value'}
>>> d.setdefault('key', 'new value')
'old value'
# 或自动生成缺少键的初始值:
>>> d = collections.defaultdict(int)
>>> d['missing key'] += 1
>>> d['missing key']
1
# 有序字典:
>>> d = collections.OrderedDict()
>>> d['x'] = 1
>>> d['y'] = 1
>>> list(d)
['x', 'y']
>>> del d['x']
>>> d['x'] = 1
>>> list(d)
['y', 'x']
上下文管理(with as )
- Non-Pythonic
resource = allocate()
try:
resource.use()
finally:
resource.deallocate()
# 打开/关闭文件
f = open('data.txt')
try:
data = f.read()
finally:
f.close()
- Pythonic
with allocate_resource() as resource:
resource.use()
# 打开/关闭文件
with open('data.txt') as f:
data = f.read()
最后一定不能忘记的操作是关闭文件,即使报错了也要 close。普通的方式是在 finnally 块中显示的调用 close 方法。
使用 with 语句,系统会在执行完文件操作后自动关闭文件对象。
装饰器
- 由于内容较多,我将用一篇博文专门介绍
字符串连接(join)
- Non-Pythonic
names = ['raymond', 'rachel', 'matthew', 'roger',
'betty', 'melissa', 'judith', 'charlie']
s = names[0]
for name in names[1:]:
s += ', ' + name
print s
- Pythonic
print ', '.join(names)
说明: join 方法整个过程只会产生一个字符串对象 使用+操作时,每执行一次+操作就会导致在内存中生成一个新的字符串对象
合理使用列表
- Non-Pythonic
names = ['raymond', 'rachel', 'matthew', 'roger',
'betty', 'melissa', 'judith', 'charlie']
names.pop(0)
names.insert(0, 'mark')
- Pythonic
from collections import deque
names = deque(['raymond', 'rachel', 'matthew', 'roger',
'betty', 'melissa', 'judith', 'charlie'])
names.popleft()
列表对象(list)是一个查询效率高于更新操作的数据结构,删除和插入需要对剩下的元素做移动操作 deque 是一个双向队列的数据结构,删除元素和插入元素会很快
序列解包
- Non-Pythonic
p = 'vttalk', 'female', 30, 'python@qq.com'
name = p[0]
gender = p[1]
age = p[2]
email = p[3]
- Pythonic
name, gender, age, email = p
遍历字典的 key 和 value
- Non-Pythonic
# 方法一
for k in d:
print k, '--->', d[k]
# 方法二
for k, v in d.items():
print k, '--->', v
- Pythonic
for k, v in d.iteritems():
print k, '--->', v
链式比较操作
- Non-Pythonic
age = 18
if age > 18 and x < 60:
print("yong man")
- Pythonic
if 18 < age < 60:
print("yong man")
行内判断 if/else 三目运算
- Non-Pythonic
if gender == 'male':
text = '男'
else:
text = '女'
- Pythonic
text = '男' if gender == 'male' else '女'
真值判断
- Non-Pythonic
if attr == True:
do_something()
if len(values) != 0: # 判断列表是否为空
do_something()
- Pythonic
if attr:
do_something()
if values:
do_something()
for/else语句
- Non-Pythonic
flagfound = False
for i in mylist:
if i == theflag:
flagfound = True
break
process(i)
if not flagfound:
raise ValueError("List argument missing terminal flag.")
- Pythonic
for i in mylist:
if i == theflag:
break
process(i)
else:
raise ValueError("List argument missing terminal flag.")
for else 是 Python 中特有的语法格式,else 中的代码在 for 循环遍历完所有元素之后执行。
字符串格式化
- Non-Pythonic
s1 = "foofish.net"
s2 = "vttalk"
s3 = "welcome to %s and following %s" % (s1, s2)
- Pythonic
s3 = "welcome to {blog} and following {wechat}".format(blog="foofish.net", wechat="vttalk")
列表切片
- Non-Pythonic
items = range(10)
# 奇数
odd_items = []
for i in items:
if i % 2 != 0:
odd_items.append(i)
# 拷贝
copy_items = []
for i in items:
copy_items.append(i)
- Pythonic
# 第1到第4个元素的范围区间
sub_items = items[1:4]
# 奇数
odd_items = items[1::2]
#拷贝
copy_items = items[::] 或者 items[:]
善用生成器
- Non-Pythonic
def fib(n):
a, b = 0, 1
result = []
while b < n:
result.append(b)
a, b = b, a+b
return result
- Pythonic
def fib(n):
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
生成器的好处就是无需一次性把所有元素加载到内存,只有迭代获取元素时才返回该元素
用Counter来计数
- Non-Pythonic
# Non-pythonic, ugly
x_list = ['Ozil', 'Ramsey', 'Ozil', 'Ramsey', 'Giroud']
x_dict = {}
for x in x_list:
if x in x_dict.keys():
x_dict[x] += 1
else:
x_dict[x] = 1
print(x_dict)
- Pythonic
from collections import Counter
x_list = ['Ozil', 'Ramsey', 'Ozil', 'Ramsey', 'Giroud']
x_dict = Counter(x_list)
print(x_dict)