Anonymous function, two built-in functions, closure

Anonymous function

Anonymous function, that function without a name, lambda, also known as word function.

There is now a demand for: Write a function, this function receives two int parameters, and return values.

def func(a,b):
    return a+b
print(func(3,4))

Completion of the above requirements with anonymous functions:

func = lambda a,b: a+b
print(func(3, 4))  # 7

Analysis of the above code:

grammar:

  Function name = lambda parameter: Return value

1) This function is not no name, he has a name, and his name is called lambda

2) lambda keyword to define an anonymous function, which is equivalent def function.

3) added directly behind the lambda parameter, how many can participate shape, as long as the line separated by commas.

func = lambda a,b,*args,sex= 'alex',c,**kwargs: kwargs
print(func(3, 4,c=666,name='alex'))  # {'name': 'alex'}
# 所有类型的形参都可以加,但是一般使用匿名函数只是加位置参数,其他的用不到。

4) return value after the colon, the return value and normal functions, may be of any data type. (But want to return multiple elements to be returned in the form of a container)

5) anonymous function no matter how complicated can only write a single line. And return directly after the end of the logical data

Then a small problem a few anonymous function:

Write anonymous function: receiving a data slice, returns the index of an element corresponding to 0 and 2 (form of tuples).

func = lambda x:(x[0],x[2])
print(func('afafasd'))

Write an anonymous function: int receives two parameters, the larger the data returned.

func = lambda x,y: x if x > y else y
print(func(3,100))

Built-in functions Ⅱ

print () screen output.

''' 源码分析
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
    """
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    file:  默认是输出到屏幕,如果设置为文件句柄,输出到文件
    sep:   打印多个值之间的分隔符,默认为空格
    end:   每一次打印的结尾,默认为换行符
    flush: 立即把内容输出到流文件,不作缓存
    """
'''

print(111,222,333,sep='*')  # 111*222*333

print(111,end='')
print(222)  #两行的结果 111222

f = open('log','w',encoding='utf-8')
print('写入文件',fle=f,flush=True)

list () will be converted into a list iterable

tuple () will be converted into a iterable tuple

dict () to create a dictionary corresponding way.

list
l1 = list('abcd')
print(l1)  # ['a', 'b', 'c', 'd']
tu1 = tuple('abcd')
print(tu1)  # ('a', 'b', 'c', 'd')

abs () returns the absolute value of

i = -5
print(abs(i))  # 5

sum () sums

print(sum([1,2,3]))
print(sum((1,2,3),100))

min () for the minimum

print(min([1,2,3]))  # 返回此序列最小值

ret = min([1,2,-5,],key=abs)  # 按照绝对值的大小,返回此序列最小值
print(ret)
# 加key是可以加函数名,min自动会获取传入函数中的参数的每个元素,然后通过你设定的返回值比较大小,返回最小的传入的那个参数。
print(min(1,2,-5,6,-3,key=lambda x:abs(x)))  # 可以设置很多参数比较大小
dic = {'a':3,'b':2,'c':1}
print(min(dic,key=lambda x:dic[x]))

# x为dic的key,lambda的返回值(即dic的值进行比较)返回最小的值对应的键

max () use the same maximum and minimum values.

reversed () will be a sequence of flip flip iterator returns reversed exemplary sequence:

l = reversed('你好')  # l 获取到的是一个生成器
print(list(l))
ret = reversed([1, 4, 3, 7, 9])
print(list(ret))  # [9, 7, 3, 4, 1]

bytes () the string into bytes Type

s = '你好'
bs = s.encode('utf-8')
print(bs)
结果:b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\xad\xa6\xe5\xa4\xa7'

s1 = bs.decode('utf-8')
print(s1)
结果: 你好


s = '你好'
bs = bytes(s,encoding='utf-8')
print(bs)
# 将字符串转换成字节

bs1 = str(bs,encoding='utf-8')
print(bs1)
# 将字节转换成字符串

zip () method of the slide fastener. Iteration function for the object as a parameter to be the corresponding element of the object packed into a tuple,

Then return the contents of these tuples composition, if the number of elements of each iterator inconsistent, according to the length of the shortest return,

lst1 = [1,2,3]

lst2 = ['a','b','c','d']

lst3 = (11,12,13,14,15)

for i in zip(lst1,lst2,lst3):

    print(i)

结果:

(1, 'a', 11)

(2, 'b', 12)

(3, 'c', 13)

sorted sort function

语法:sorted(iterable,key=None,reverse=False)

iterable : 可迭代对象

key: 排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序

reverse :是否是倒序,True 倒序 False 正序

lst = [1,3,2,5,4]
lst2 = sorted(lst)
print(lst)    #原列表不会改变
print(lst2)   #返回的新列表是经过排序的


lst3 = sorted(lst,reverse=True)
print(lst3)   #倒叙

结果:
[1, 3, 2, 5, 4]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

字典使用sorted排序

dic = {1:'a',3:'c',2:'b'}
print(sorted(dic))   # 字典排序返回的就是排序后的key

结果:
[1,2,3]

和函数组合使用

# 定义一个列表,然后根据一元素的长度排序
lst = ['天龙八部','西游记','红楼梦','三国演义']

# 计算字符串的长度
def func(s):
    return len(s)
print(sorted(lst,key=func))

# 结果:
# ['西游记', '红楼梦', '天龙八部', '三国演义']


和lambda组合使用

lst = ['天龙八部','西游记','红楼梦','三国演义']

print(sorted(lst,key=lambda s:len(s)))

结果:
['西游记', '红楼梦', '天龙八部', '三国演义']


lst = [{'id':1,'name':'alex','age':18},
    {'id':2,'name':'wusir','age':17},
    {'id':3,'name':'taibai','age':16},]

# 按照年龄对学生信息进行排序

print(sorted(lst,key=lambda e:e['age']))

结果:
[{'id': 3, 'name': 'taibai', 'age': 16}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'alex', 'age': 18}]

filter filter filter

语法: filter(function,iterable)

function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据

iterable:可迭代对象

lst = [{'id':1,'name':'alex','age':18},
        {'id':1,'name':'wusir','age':17},
        {'id':1,'name':'taibai','age':16},]

ls = filter(lambda e:e['age'] > 16,lst)

print(list(ls))

结果:
[{'id': 1, 'name': 'alex', 'age': 18},
 {'id': 1, 'name': 'wusir', 'age': 17}]

map map

映射函数

语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function

计算列表中每个元素的平方,返回新列表

lst = [1,2,3,4,5]

def func(s):

    return  s*s

mp = map(func,lst)

print(mp)

print(list(mp))


改写成lambda

lst = [1,2,3,4,5]

print(list(map(lambda s:s*s,lst)))


计算两个列表中相同位置的数据的和

lst1 = [1, 2, 3, 4, 5]

lst2 = [2, 4, 6, 8, 10]

print(list(map(lambda x, y: x+y, lst1, lst2)))

结果:

[3, 6, 9, 12, 15]

imgreduce

from functools import reduce
def func(x,y):
    return x + y

# reduce 的使用方式:
# reduce(函数名,可迭代对象)  # 这两个参数必须都要有,缺一个不行

ret = reduce(func,[3,4,5,6,7])
print(ret)  # 结果 25
reduce的作用是先把列表中的前俩个元素取出计算出一个值然后临时保存着,
接下来用这个临时保存的值和列表中第三个元素进行计算,求出一个新的值将最开始
临时保存的值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算.依次类推

注意:放进去的可迭代对象没有更改
以上这个例子使用sum就可以完全的实现了.现在有[1,2,3,4]想让列表中的数变成1234,就要用到reduce了.
普通函数版
from functools import reduce

def func(x,y):

    return x * 10 + y
    # 第一次的时候 x是1 y是2  x乘以10就是10,然后加上y也就是2最终结果是12然后临时存储起来了
    # 第二次的时候x是临时存储的值12 x乘以10就是 120 然后加上y也就是3最终结果是123临时存储起来了
    # 第三次的时候x是临时存储的值123 x乘以10就是 1230 然后加上y也就是4最终结果是1234然后返回了

l = reduce(func,[1,2,3,4])
print(l)

Closure

For example: the average closing price of a commodity throughout history. What is the draw closing price of it? It was from this commodity appears to start a record price during the day every day, and then calculate his average: the average price to be considered until all so far.

For example, Volkswagen introduced a new car: small white car.

The first day price: 100,000 yuan, the average closing price: 100,000 yuan

The next day price: 110 000 yuan, the average closing price: (100000 + 110000) / 2 yuan

Day price: 120 000 yuan, the average closing price: (100,000 + 110,000 + 120,000) / 3 yuan

........

series = []
def make_averager(new_value):
    series.append(new_value)
    total = sum(series)
    return total / len(series)

print(make_averager(100000))
print(make_averager(110000))
print(make_averager(120000))

As can be seen from the above example, basically completed the requirements, but this code is relatively insecure, because your list this series is a global variable, as long as anywhere in the global scope, are likely on this list change.

series = []
def make_averager(new_value):
    series.append(new_value)
    total = sum(series)
    return total / len(series)

print(make_averager(100000))
print(make_averager(110000))
series.append(666)  # 如果对数据进行相应改变,那么你的平均收盘价就会出现很大的问题。
print(make_averager(120000))

So how to do it? Some people say, you put him in function is not on the line, this is not meant to be local yet? Data is not relatively safe yet?

def make_averager(new_value):
    series = []
    series.append(new_value)
    total = sum(series)
    return total / len(series)


print(make_averager(100000))  # 100000.0
print(make_averager(110000))  # 110000.0
print(make_averager(120000))  # 120000.0

The results of such calculations are not correct, it is because the function is executed, it will open a temporary namespace disappear with the end of the function, so each time you perform a function, is to re-create this list, then this is how do it? In this case, we need to use the closure, with the closure of ideas to change what this code.

def make_averager():

    series = []
    def averager(new_value):
        series.append(new_value)
        total = sum(series)
        return total/len(series)

    return averager

avg = make_averager()
print(avg(100000))
print(avg(110000))
print(avg(120000))

Function in a nested function. So avg received this variable is averager actual function name, which is the corresponding memory address, which is performed three times avg three averager perform this function.

Closure package definition:

  1. Function is nested within the closure function.
  2. Closures must be a variable function of the outer layer of the inner function (non-global variable) reference.

How to determine the judge closures?

# 例一:
def wrapper():
    a = 1
    def inner():
        print(a)
    return inner
ret = wrapper()

# 例二:
a = 2
def wrapper():
    def inner():
        print(a)
    return inner
ret = wrapper()


# 例三:

def wrapper(a,b):
    def inner():
        print(a)
        print(b)
    return inner
a = 2
b = 3
ret = wrapper(a,b)

The above three examples, is the third most difficult to judge, in fact, the third and closure, every time I go into the code to determine if it is not closure, there are some unscientific, or too much trouble, then there are some functions can obtain this property is a function of whether it has free variables, if this function has free variables, it can be the side that whether it is a function of the closure ( to know ):

def make_averager():

    series = []
    def averager(new_value):
        series.append(new_value)
        total = sum(series)
        return total/len(series)

    return averager
avg = make_averager()
# 函数名.__code__.co_freevars 查看函数的自由变量
print(avg.__code__.co_freevars)  # ('series',)
当然还有一些参数,仅供了解:

# 函数名.__code__.co_freevars 查看函数的自由变量
print(avg.__code__.co_freevars)  # ('series',)
# 函数名.__code__.co_varnames 查看函数的局部变量
print(avg.__code__.co_varnames)  # ('new_value', 'total')
# 函数名.__closure__ 获取具体的自由变量对象,也就是cell对象。
# (<cell at 0x0000020070CB7618: int object at 0x000000005CA08090>,)
# cell_contents 自由变量具体的值
print(avg.__closure__[0].cell_contents)  # []

Action closures : Save local information is not destroyed, to ensure data security.

Application package closure :

  1. You can save some of the non-global variables but can not easily be destroyed, changed data.
  2. Decorator.

Guess you like

Origin www.cnblogs.com/sundawei7/p/11228835.html