培养python思维(1)

对于Python新手来说,写代码很少考虑代码的效率和简洁性,因此容易造成代码冗长、执行慢,这些都是需要改进的地方。本文是想通过几个案列给新手一点启发,怎样写python代码更优雅。

一、与第三方库相比,同样强大的标准库

标准库itertools和collections仍然很少被初学者使用

itertools

如果你看到下面的任务:

list1 = range(1,10)
list2 = range(10,20)
for item1 in list1:
    for item2 in list2:
        print(item1*item2)

这是一个嵌套循环操作,为提高代码效率,完全可以用product()函数替代嵌套循环:

from itertools import product
list1 = range(1,10)
list2 = range(10,20)
for item1,item2 in product(list1, list2):
    print(item1*item2)

这两段代码的结果完全一样,但使用标准库函数明显更加简洁高效。itertools还有很多方便操作迭代对象的函数,比如:

  • count()函数会创建一个无限迭代器
  • cycle()函数会把传入的序列无限重复下去
  • chain()可以把多个迭代对象串联起来
  • group()函数可以把迭代其中相邻的重复元素挑出来,放在一起

    有兴趣可以详细看看itertools库的各种神奇函数

collections

新手对python集合模块了解的可能并不多,你可能会遇到这样的情形:

consolidated_list = [('a',1),('b',2),('c',3),('b',4)]
items_by_id = {}
for id_, item in consolidated_list:
    if id_ not in items_by_id: 
        items_by_id[id_] = []
    if id_ in items_by_id:
        items_by_id[id_].append(item)

上面代码构建了一个字典,依次向字典中添加信息,如果某个键已经存在,则以某种方式修改该键的值;如果某个键不存在,则添加对应键值对。

这种算法非常常见,你可以用collects模块的defaultdict()函数来实现同样效果:

from collections import defaultdict
 
items_by_id = defaultdict(list)
consolidated_list = [('a',1),('b',2),('c',3),('b',4)]

for id_, item in consolidated_list:
    items_by_id[id_].append(item)

在此列中,defaultdict()接受一个list作为参数,当键不存在时,则返回一个空列表作为对应值。

有时候我们会遇到统计词频的案例,比如:

# 统计词频
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
result = {}
for color in colors:
    if result.get(color)==None:
        result[color]=1
    else:
        result[color]+=1
print (result)
# 输出 {'red': 2, 'blue': 3, 'green': 1}

完全可以用defaultdict()函数实现上面的计数功能:

colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
d = defaultdict(int)
for color in colors:
    d[color] += 1
print(d)

更简单的方法用collections模块的Counter()函数:

from collections import Counter
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
c = Counter(colors)
print (dict(c))

对于备份文件,新人往往会用system模块:

from  os import system
system("xcopy e:\\sample.csv  e:\\newfile\\")

其实shutil模块更好用:

import shutil
shutil.copyfile('E:\\q.csv', 'e:\\movie\\q.csv')

因为shutil会很详细地报告错误和异常。

二、生成器

除非你的list十分复杂,并且频繁调用,否则都建议使用生成器,因为它非常节省内存,举个例子:

def powers_of_two(max=20000):
    i = 0
    powers = []
    while 2**i < max:
        powers.append[2**i]
        i += 1
    return powers

对于使用次数少、占据大量内存、且容易生成的数据,可以用生成器替代列表存储:

from itertools import count, takewhile
def powers_of_two(max=20000):
    for index in takewhile(lambda i: 2**i < max, count(start=0)):
        yield 2**index

本文部分内容节选自Tony Flury在Quora的回答

你可能感兴趣的:(python库实例)