(1)命名切片
:
通过切片命名我们可以避免硬编码,使得代码的可读性更好:
Price = slice(3,5)#用来获取价格部分的切片
price = items[Price]
可以通过.indices方法可以适当的缩小边界避免越界:
(2)Counter和most_common
word_count其实就是将每一个元素映射到一个字典上,然后most_common应该是利用了类似nsamllest的算法获取相应的对象,update方法可以增加计数统计。
word_count = Counter(['a','a','b','c'])
print(word_count.most_common(3))
word_count.update(['d','v'])
此外,Counter还可以进行数学运算:
word_count_2 = Counter(['e','v'])
print(word_count+word_count_2)
print(word_count-word_count_2)
也可以直接减去某一个元素的次数:注意,这样会造成次数为负数。
word_count.subtract(['d','d'])
(3)使用operator模块的itemgetter,attrgetter代替lambda表达式,这样运行效率会高一点
rows_by_lfname = sorted(rows, key=itemgetter('lname','fname'))
by_name = sorted(users, key=attrgetter('last_name', 'first_name'))
(4)过滤序列元素
其实我们都很熟悉的列表推导就是用来进行序列过滤的,但是其实还是有一些可以注意的地方。另外字典推导,集合推导也是很有用的!
[0]使用生成器的列表推导:避免内存消耗太大
s=((i,i+5) for i in a if i>2)
[1]使用filter函数进行过滤
def check(x):
if x%2==0 or x<5:return False
return x**3
ans = filter(check,values)
[2]:使用compress进行序列选择,适用于需要用另外一个相关联的序列来过滤某个序列的时候。关键是创建一个boolean序列来指定哪些位置是应该选取的元素。注意这个是利用位置进行的索引的。
values = [1,2,3,4,5,6,7,8,9]
count = [1,2,3,4,5,6]
bool = [n>5 for n in count]
print(list(compress(values,bool)))
(5)namedtuple
一个命名元组可以帮助我们的代码显得更加清晰,而且可以避免过于依赖数据的存放结构导致容易出错(使用下标访问就存在这个问题)。
Stock = namedtuple('Stock',['name','price','amount'])
def compute_cost(records):
total = 0.0
for rec in records:
stock = Stock(*rec)
total += stock.price * stock.amount
return total
当我们修改records里面的数据结构时,只需要修改Stock的定义即可。而内部的代码可以保持不变。
(6)
转换并同时计算数据:利用生成器表达式,我们居然可以只写一个括号就搞定计算。同样的方式还可以用于man,min,any等方法。
s = sum((x * x for x in nums))
s = sum(x * x for x in nums)
(7)合并多个字典或者映射:ChainMap
当我们想在逻辑上对几个字典进行合并,可以进行如下操作
a = {'a':1}
b = {'b':2}
c = ChainMap(a,b)
这样如果对c中的元素进行查找,会按照顺序进行。先查a,再查b。另外,任何对于c的操作都只在第一个映射上进行。注意,和update方法不一样,ChainMap只是把原来的字典用列表存储起来,不会生成新的字典。同时原来的字典结构改变也会影响到ChainMap。保证了信息的传递。
c.pop('b')
还可以利用new_child和parent方法灵活的添加并生成新的ChainMap.
c = ChainMap(a,b)
d = c.new_child()
d['x'] = 3
print(c,d,d.parents)