python之lambda,random,timeit,collections,

python之lambda,random,timeit,collections,
一、
 python之lambda函数
lambda函数又称为匿名函数,匿名函数就是没有函数名的函数。
>>> lambda x,y:x+y
<function <lambda> at 0x7f0f0dd85578>
x,y是函数的两个变量,位于冒号的左边,冒号右边的表达式是函数的返回值。
>>> add =lambda x,y:x+y
>>> add
<function <lambda> at 0x7f0f0dd855f0>
>>> add(1,2)
等同于函数    
def add(x,y):
    return x+y
add(1,2)

lambda的使用场景
1.函数式编程
#例如:一个整数列表,要求按照列表中元素的绝对值大小升序排列
list1 = [3,5,-4,-1,0,-2,-6]
print(sorted(list1,key=abs))
print(sorted(list1,key=lambda x:abs(x)))
 
2.python中最常见的filter筛选、map小刷子、reduce合并,都可以用lambda表达式来生成。对于序列来讲,有三个函数式编程工具:filter()、map()、reduce()
map(function,sequence):把sequence中的值当参数逐个传给function,返回一个包含函数执行结果的list。如果function有两个参数,即map(function,sequence1,sequence2)。
#求1~20的平方
print(list(map(lambda x:x**2,range(1,21))))
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400]
 
filter(function,sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)返回。
#求1~20之间的偶数
print(list(filter(lambda x:x%2 == 0,range(1,21))))
#[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
 
reduce(function,sequence):function接收的参数个数只能为2,先把sequence中第一个值和第二个值当参数传给function,再把function的返回值和第三个值当参数传给function,然后只返回一个结果。
#求1~100之和
from functools import reduce
print(reduce(lambda x,y:x+y,range(1,101)))
#5050
 
#求1~100之和,再加上10000
from functools import reduce
print(reduce(lambda x,y:x+y,range(101),10000))
#15050
 
3.闭包
一个定义在函数内部的函数,内部函数使用了外部函数的临时变量,并且外部函数的返回值是内部函数的引用。
 
def outer(a):
    b=10
        def inner(): # 内部函数
            print(a+b)
        return inner # 外函数的返回值是内函数的引用
outer(5)
二、
python之random模块
import random
 
print(random.random()) #用于生成一个0到1之间的随机浮点数
print(random.uniform(1,3))# 用于生成一个指定范围内的随机浮点数
print(random.uniform(3,1))# 两个参数一个是上限,一个是下限。
print(random.randint(1,3)) # 用于生成一个指定范围内的整数。
#random.randrange([start],stop[,step]) 从指定范围内,按指定的基数递增的集合中获取一个随机数
print(random.randrange(0,100,2)) # 取 0到100之间的随机偶数
 
# random.choice 从序列中获取一个随机元素。其函数原型为random.choice(sequence),参数sequence表示
# 一个有序类型。
print(random.choice('改变世界')) # 世
print(random.choice(['sunshine','is','lower'])) #lower
print(random.choice(('sunshine','always','18')))  # 18
 
# random.shuffle(x[,random]) 用于将一个列表中的元素打乱。
 
s = ['改','变','世','界']
random.shuffle(s)
print(s) # ['变', '世', '改', '界']
 
# random.sample(sequence,k) 从指令序列中随机获取指定长度的片段。sample函数不会修改原有的序列。
l = [1,2,3,4,5,6,7,8]
print(random.sample(l,3)) # [7, 3, 5]

三、
python之collection模块
collections 是python内建的一个集合模块。

namedtuple可以很方便的定义一种数据类型,他具备tuple的不可变性,也可以根据属性来引用,非常方便。

from collections import  namedtuple
point = namedtuple('p',['x','y'])
p = point(1,2)
print(p.x) #1
print(p.y) #2

# namedtuple('名称', [属性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])

deque可以高效的实现插入和删除的双向列表,适用于队列和栈。
from collections import deque
q= deque(['a','b','c'])
q.append('x')
q.appendleft('y')
print(q)
 
#deque(['y', 'a', 'b', 'c', 'x'])

defaultdict

使用dict时,如果key不存在,则抛出KeyError,如果希望key不存在时,返回一个默认值,可以用defaultdict。

from collections import defaultdict
dic = defaultdict(lambda :'N/A')
dic['k1'] = 'abc'
print(dic['k1']) #‘abc’
print(dic['k2']) #N/A

OrderedDict

使用dict时,key是无序的,如果要保证key的顺序,可以用OrderedDict。OrderedDict的key是按照插入的顺序排列,不是key本身排序。

from collections import OrderedDict
dic = dict([('a',1),('b',2),('c',3)])
dic1 = OrderedDict([('a',1),('b',2),('c',3)])
print(dic.keys()) #dict_keys(['a', 'b', 'c'])
print(dic1.keys()) #odict_keys(['a', 'b', 'c'])

Counter是一个简单的计数器,目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储。其中元素为key,个数为value. 计数值可以是任意的interger(含0和负数)

from collections import Counter
c = Counter('abcdeabcdabcaba')
print(c)

    
输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

四、
python之timeit模块
timeit模块:

    timeit 模块定义了接受两个参数的 Timer 类。两个参数都是字符串。 第一个参数是你要计时的语句或者函数。 传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入语句。 从内部讲, timeit 构建起一个独立的虚拟环境, 手工地执行建立语句,然后手工地编译和执行被计时语句。

    一旦有了 Timer 对象,最简单的事就是调用 timeit(),它接受一个参数为每个测试中调用被计时语句的次数,默认为一百万次;返回所耗费的秒数。
    Timer 对象的另一个主要方法是 repeat(), 它接受两个可选参数。 第一个参数是重复整个测试的次数,第二个参数是每个测试中调用被计时语句的次数。 两个参数都是可选的,它们的默认值分别是 3 和1000000。 repeat() 方法返回以秒记录的每个测试循环的耗时列表。Python 有一个方便的 min 函数可以把输入的列表返回成最小值,如: min(t.repeat(3, 1000000))

  测试一个列表推导式与for循环的时间

import timeit
foooo = """
sum = []
for i in range(1000):
    sum.append(i)
"""
 
print(timeit.timeit(stmt="[i for i in range(1000)]", number=100000))
print(timeit.timeit(stmt=foooo, number=100000))
 
#res:
#3.2855970134734345
#8.19918414604134

  使用列表推导式要比正常使用list追加元素 通过10w次循环会快上近5秒左右,速度快上近三倍。

  timeit 模块抽象出了;两个可以直接使用的方法,包了一层可以让我们不用关心内部的实现,下面看一下模块里面的代码:

def timeit(stmt="pass", setup="pass", timer=default_timer,
           number=default_number):
    """Convenience function to create Timer object and call timeit method."""
    return Timer(stmt, setup, timer).timeit(number)
 
def repeat(stmt="pass", setup="pass", timer=default_timer,
           repeat=default_repeat, number=default_number):
    """Convenience function to create Timer object and call repeat method."""
    return Timer(stmt, setup, timer).repeat(repeat, number)

  可以看到这两个方法都是对Timer类包了一层这几个参数:

  stmt: 这个参数就是statement,可以把要进行计算时间的代码放在里面。他可以直接接受字符串的表达式,也可以接受单个变量,也可以接受函数。

  setup:  这个参数可以将stmt的环境传进去。比如各种import和参数什么的。

  timer: 这个参数一般使用不到,具体使用可以参看文档。

  Timer类下面还有repeat和timeit方法 使用也非常方便就是 timeit.timeit 和  timeit.repeat。

  一个就是上面例子的timeit,一个就是repeat 其实repeat就比timeit多了一个执行Timer次数的参数。这个执行次数会以数组的形式返回.

import timeit
 
foooo = """
sum = []
for i in range(1000):
    sum.append(i)
"""
 
print(timeit.repeat(stmt="[i for i in range(1000)]", repeat=2, number=100000))
print(min(timeit.repeat(stmt="[i for i in range(1000)]", repeat=2, number=100000)))
 
#res:
#[3.4540683642063277, 3.300991128415932]
#3.321008256502136

  我们可以根据此,对所有执行时间取min最小值,平均值,最大值得到我们想要的数据。

    
# coding: utf-8
import timeit
 
# 初始化类
x = """
say_hi.ParseFromString(p)
"""
 
y = """
simplejson.loads(x)
"""
 
print(timeit.timeit(stmt=x, setup="import say_hi_pb2;"
                                  "say_hi = say_hi_pb2.SayHi();"
                                  "say_hi.id = 13423;"
                                  "say_hi.something = 'axiba';"
                                  "say_hi.extra_info = 'xiba';"
                                  "p =say_hi.SerializeToString()", number=1000000))
 
print(timeit.timeit(stmt=y, setup="import simplejson; "
                                  "json={"
                                  "'id': 13423,"
                                  "'something': 'axiba',"
                                  "'extra_info': 'xiba',"
                                  "};"
                                  "x = simplejson.dumps(json)", number=1000000))<br> 

另外需要补充一点是,如果你想直接 stmt 那里执行函数。可以把函数申明在当前文件中,然后在 stmt = ‘func()’ 执行函数。然后使用 setup = ‘from __main__ import func’ 即可,如果要import 多个需要使用 setup = from __main__ import func; import simplejson'

    
def test1():
    n=0
    for i in range(101):
        n+=i
    return n
def test2():
    return sum(range(101))
def test3():
    return sum(x for x in range(101))
if __name__=='__main__':
    from timeit import Timer
    t1=Timer("test1()","from __main__ import test1")
    t2=Timer("test2()","from __main__ import test2")
    t3=Timer("test3()","from __main__ import test3")
    print(t1.timeit(10000))
    print(t2.timeit(10000))
    print(t3.timeit(10000))
    print(t1.repeat(3,10000))
    print(t2.repeat(3,10000))
    print(t3.repeat(3,10000))
    t4 = timeit.timeit(stmt=test1,setup="from __main__ import test1",number=10000)
    t5 = timeit.timeit(stmt=test2,setup="from __main__ import test2",number=10000)
    t6 = timeit.timeit(stmt=test3,setup="from __main__ import test3",number=10000)
    print(t4) #0.05130029071325269
    print(t5) #0.015494466822610305
    print(t6) #0.05650903115721077
    print(timeit.repeat(stmt=test1,setup="from __main__ import test1",number=10000)) # [0.05308853391023148, 0.04544335904366706, 0.05969025402337652]
    print(timeit.repeat(stmt=test2,setup="from __main__ import test2",number=10000)) # [0.012824560678924846, 0.017111019558035345, 0.01429126826003152]
    print(timeit.repeat(stmt=test3,setup="from __main__ import test3",number=10000)) # [0.07385010910706968, 0.06244617606430164, 0.06273494371932059]
 
#res:
0.043916918200588385
0.014892355541932578
0.05214884436618059
[0.04372713709398021, 0.04197132052492908, 0.04255431716177577]
[0.014356804181737959, 0.012456603785177323, 0.012629659578433372]
[0.0543709217115389, 0.05334180294099272, 0.05334931226535494]

五、
装饰器
原文:https://www.cnblogs.com/Uncle-Guang/p/8862183.html

猜你喜欢

转载自www.cnblogs.com/lisa2016/p/11688263.html