funcy中的实用API
funcy的设计宗旨就是汇集一系列花哨的实用函数,其在不断地迭代过程中,已经积累下相当多的功能
无限计数器
funcy
中的count()
可以生成一个可指定起点和步长的无限迭代器,默认参数start=0
,step=1
,我们可以用它来替代常规的while循环
+自增变量
的逻辑:
import funcy as fc
for i in fc.count():
print(i, end='\r')
# 当i大于等于5时停止迭代,否则继续
if i >= 5:
break
展平嵌套数组
funcy
中的flatten()
可以用来展平任意的嵌套数组:
import funcy as fc
arr1=[1,2,3,[4,5,6,[8,7,6,7,2],[23,12,1]],234,12]
arr2=[[123,456],'123','a','b','c']
print(list(fc.flatten(arr1)))
print(list(fc.flatten(arr2)))
#[1, 2, 3, 4, 5, 6, 8, 7, 6, 7, 2, 23, 12, 1, 234, 12]
#[123, 456, '123', 'a', 'b', 'c']
在指定数组中插其它
funcy
中的interpose()
可以用来将指定元素插入到对应数组的两两元素之间:
import funcy as fc
arr=['1','123','a','b','c']
print(list(fc.interpose("test",arr)))
#['1', 'test', '123', 'test', 'a', 'test', 'b', 'test', 'c']
批量删除满足指定条件的元素
在funcy
中有两种从原始列表中删除指定元素的方法,方式1是使用remove()
来传入条件判断函数来删除满足条件的元素,类似filter()
的方式:
import funcy as fc
arr=[None,'1','123','a','b','c','']
print(list(fc.remove(lambda x: x == None or x == "",arr)))
#['1', '123', 'a', 'b', 'c']
第二种方式是利用funcy
中的without()
,它可以帮我们从原始数组中排除指定的1个或多个元素,譬如下面我们把2、5、7、9排除掉:
import funcy as fc
print(list(fc.without(list(range(10))*2, 2,5,7,9)))
#[0, 1, 3, 4, 6, 8, 0, 1, 3, 4, 6, 8]
等长度拆分数组
- 等长度拆分数组,丢弃末尾长度不足的部分
funcy
中的partition()
帮助我们对输入的数组做指定长度的切片划分,譬如下面的例子,我们对列表[0, 1, ..., 10]进行长度为3的切片拆分,剩余不足长度3的部分就会被丢弃:
import funcy as fc
print(list(fc.partition(3,list(range(11)))))
#[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
- 等长度拆分数组,并保留长度不足的部分
与partition()
功能相似,funcy
中的chunks()
会在等长度拆分数组的同时,保留末尾长度不足的部分单独输出:
import funcy as fc
print(list(fc.chunks(3,list(range(11)))))
#[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
合并多个同类型对象
利用merge()
,我们可以将传入的多个同类型数据结构拼成一个完整的,这在合并集合或字典时尤其受用:
import funcy as fc
l1= list(range(6))
l2= list(range(6,10))
print(list(fc.merge(l1,l2)))
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
阻止函数遇到错误时的常规报错方式
如果我们并不希望遇到错误就中断的话,就需要自己写额外的try...except...
逻辑,而funcy
中的silent()
则可以让这个过程变得很省事:
import funcy as fc
def func(num):
if fc.silent(int)(num) or num ==0:
print('ok,It`s int')
else:
print("not int")
func(-66.3)
#ok,It`s int
阻止函数遇到指定错误时的常规报错方式
上面介绍的silent()
会帮助传入函数遇到任意错误时返回None
,而funcy
中的ignore()
则赋予我们指定错误类型,以及报错时设定返回值的能力:
import funcy as fc
def func(num):
return 100/num
# print(func(0))
#ZeroDivisionError: division by zero
print(fc.ignore(errors=(ZeroDivisionError),default="被除数不能为0")(func)(0)
#被除数不能为0
装饰指定函数,使其记忆历史执行记录值
下面要介绍的方法非常的实用,想象一下这样的场景:你书写的某个函数接受输入,然后经过一段耗时不菲的计算过程输出结果,但在函数实际调用过程中经常遇到重复的传入参数。
这种时候你肯定希望自己的函数可以“记忆”下执行过的参数与输出结果,省得大量重复计算,而funcy
中的memoize
装饰器就可以帮助我们快速改造自己的函数:
import funcy as fc
import math
@fc.memoize
def job(x):
return round(math.log(x**2 /10),4)
test = [job(5) for i in range(1000000)]
test = [job(10) for i in range(1000000)]
print(job.memory)
#{(5,): 0.9163, (10,): 2.3026}
#清空缓存
job.memory.clear()
约束某个函数的可执行次数
有些情况下,我们希望程序中的某个函数在整个程序的生命周期中只执行一次,譬如创建数据库连接等操作时,而funcy
中提供的装饰器once
就可以帮助我们快速实现这个功能,并且保证了线程安全:
import funcy as fc
@fc.once
def job(x):
return round(math.log(x**2 /10),4)
print(job(10))
print(job(12))
#2.3026
#None