内置函数及匿名函数

思维导图:https://www.processon.com/mindmap/5a042b30e4b06c8e108f03ad

一、作用域相关:globals()和locals()

  globals():全局作用域中的变量,无论放在全局命名空间还是在局部命名空间,输出结果一样,都是全局中的变量

  locals():放在全局命名空间时和globals()效果一致,放在局部命名空间输出局部空间的变量

def func():
    x = 1
    y = 2
func()
print(locals())
print(globals())
#输出结果一致,均为全局变量
def func():
    x = 1
    y = 2
    print(locals())  # {'y': 2, 'x': 1}
    print(globals())    
func()
#前者输出局部变量,后者输出全局变量

二、迭代器/生成器相关(3)range()、iter()、next()

从迭代器取值‘
1、list()
2、next
3、for
View Code

  rangerange(start, stop[, step])

    start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);

    end: 计数到 end 结束,但不包括 end。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5,顾头不顾尾

    step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)

   可迭代对象,可用于for循环得到0-n间的整数,包括0,不包括n

print(range(10))             #结果为:range(0,10)
for i in range(10):
    print(i)                 #结果为:0 1 2 3 4 5 6 7 8 9
for i in range(1,10,2):
    print(i)
1
3
5
7
9

 

 iter(): iter(object[, sentinel])

     object:支持迭代的集合对象

    将可迭代对象转变为迭代器,用来生成迭代器。等价于:可迭代对象.__iter__()

from collections import Iterable
from collections import  Iterator
lst=[1,2,3,4,5]
print(isinstance(lst,Iterable))                  #输出结果:True---是否可迭代对象
print(isinstance(lst.__iter__(),Iterator))       #输出结果:True---是否迭代器
print(isinstance(iter(lst),Iterator))            #输出结果:True---是否迭代器

  next():返回迭代器的下一个值。next(迭代器)等价于迭代器.__next__()

eg:1、
k=iter([1,2,3,4]) print(k.__next__()) #输出结果为:1 print(next(k)) #输出结果为:2
eg:2、
k=iter([1,2,3,4]) # __iter__([1,2,3,4]) while True: try: print(next(k)) except StopIteration: #超出迭代器的层数就退出循环 break

三、字符串类型代码执行相关(3):eval()、exec()、compile()

  eval():执行字符串表达式,并返回表达式的值

print(eval('2*2'))                             #输出结果:4
x=3
print(eval('7*x'))                             #输出结果:21

  exec():执行字符串代码,无返回值

print('123456')
exec ("print('123456')")   #--> "print('123456')"python代码,必须是一段合法的代码
eval ("print('123456')")   #--> "print('123456')"python代码
print(exec('1+2+3-4'))   # None  exec('1+2+3-4')内部已计算,但没有返回
print(eval('1+2+3-4'))   # 2    用于值计算的时候

exec 用于流程性代码的执行   没有返回值
eval  用于值计算的时候      有返回值
exec("print('12345')")  # 12345
eval("print('12345')")  # 12345
print(exec('1+2+3-4'))  # None  没有返回值
print(eval('1+2+3-4'))  # 2
a = 1+2+3-4
print(1+2+3-4)           # 2

   compile  将字符串类型的代码编译。代码对象能够通过exec语句来执行或者eval()进行求值。

参数说明:   

1. 参数source:字符串或者AST(Abstract Syntax Trees)对象。即需要动态执行的代码段。  

2. 参数 filename:代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。当传入了source参数时,filename参数传入空字符即可。  

3. 参数model:指定编译代码的种类,可以指定为 ‘exec’,’eval’,’single’。当source中包含流程语句时,model应指定为‘exec’;当source中只包含一个简单的求值表达式,model应指定为‘eval’;当source中包含了交互式命令语句,model应指定为'single'。

code1 = 'for i in range(0,10): print (i)'
compile1 = compile(code1,'','exec')
exec (compile1)


#简单求值表达式用eval
code2 = '1 + 2 + 3 + 4'
compile2 = compile(code2,'','eval')
eval(compile2)


#交互语句用single
code3 = 'name = input("please input your name:")'
compile3 = compile(code3,'','single')

  

五、输入和输出函数(2):input() :input(*args, **kwargs)

      print() :print(self, *args, sep=' ', end=' ', file=None):

 input() :input(*args, **kwargs)  

 注意python3 里 input() 默认接收到的是 str 类型。

s = input("请输入内容 : ")  #输入的内容赋值给s变量
print(s)  #输入什么打印什么。数据类型是str

    :py2:input() 和 raw_input() 这两个函数均能接收 字符串 ,但 raw_input() 直接读取控制台的输入(任何类型的输入它都可以接收)。而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它会引发一个 SyntaxError 。

除非对 input() 有特别需要,否则一般情况下推荐使用 raw_input() 来与用户交互。

print() :print(self, *args, sep=' ', end='
', file=None): 
print(value, ..., sep=' ', end=' ', file=sys.stdout, flush=False) file: 默认是输出到屏幕,如果设置为文件句柄,输出到文件 sep: 打印多个值之间的分隔符,默认为空格 end: 每一次打印的结尾,默认为换行符 flush: 立即把内容输出到流文件,不作缓存
sep关键字
print
(1,2,3,4,sep= '*') # 1*2*3*4
print(1,2,sep=',')  # 1,2
print('%s,%s'%(1,2))  # 1,2

 可以把光标移动到行首但不换行
file 关键字
f = open('tmp_file','w') print(123,456,sep=',',file = f,flush=True)
万能进度条
import
time import sys for i in range(0,101,2): time.sleep(0.1) char_num = i//2 per_str = ' %s%% : %s ' % (i, '*' * char_num) if i == 100 else ' %s%% : %s' % (i, '*' * char_num) print(per_str,end='',file = sys.stdout,flush=True) import time for i in range(0,101,2): #[0,2,4,6,8...100] time.sleep(0.2) char_num = i//2 #打印多少个'|' 8/2 = 4 if i == 100: per_str = ' %s%% : %s ' % (i, '|' * char_num) else: per_str = ' %s%% : %s'%(i,'|'*char_num) print(per_str,end='', flush=True) print('你好') print('再见')

 六、内存相关函数(2):hash()  、id()

hash():hash(*args, **kwargs):

  hash(o) o是参数,返回一个可hash变量的哈希值,不可hash的变量被hash之后会报错。

      用于获取取一个对象(字符串或者数值等)的哈希值

t = (1,2,3)    #元组属于不可变的对象,不能在原地修改内容,没有排序,修改等操作。
print(hash(t))  # 可hash
l = [1,2,3]
print(hash(l))   # 报错

  hash函数会根据一个内部的算法对当前可hash变量进行处理,返回一个int数字。

  #hash 判断一个数据类型是否可以hash
  #在一个程序执行的过程中,对同一个值hash的结果总是不变
  #多次执行,对同一个值的hash结果可能改变

  *每一次执行程序,内容相同的变量hash值在这一次执行过程中不会发生改变。

id(o): o是参数,返回一个变量的内存地址

文件操作相关:open

open()  打开一个文件,返回一个文件操作符(文件句柄)

操作文件的模式有r,w,a,r+,w+,a+ 共6种,每一种方式都可以用二进制的形式操作(rb,wb,ab,rb+,wb+,ab+)

可以用encoding指定编码.

r:  以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。

 r+:  打开一个文件用于读写。文件指针将会放在文件的开头。

rb:  以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。

w:  打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。

w+:  打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。

a:  打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容   之后。如果该文件不存在,创建新文件进行写入。

a+:  打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不   存在,创建新文件用于读写。

七、与模块操作相关:__import__

__import__导入一个模块

返回元组列表。

八、帮助模块:help

  在控制台执行help()进入帮助模式。可以随意输入变量或者变量的类型。输入q退出

  或者直接执行help(o),o是参数,查看和变量o有关的操作

其他方法
ctrl + 左键单击 :pycharm
help:包含所有方法名以及他的使用方法 —— 不知道用法
dir:只包含方法名 —— 想查看某方法是否在这个数据类型中

九、与调用相关:callable(返回True或者False)

callable(o),o是参数,看这个变量是不是可调用。

对于函数, 方法, lambda 函式, 类, 以及实现了 __call__ 方法的类实例, 它都返回 True。

def func():pass
print(callable(func))  #参数是函数名,可调用,返回True
print(callable(123))   #参数是数字,不可调用,返回False

十、查看内置属性 : dir()

dir() 默认查看全局空间内的属性,也接受一个参数,查看这个参数内的方法或变量

print(dir(list))  #查看列表的内置方法
print(dir(int))  #查看整数的内置方法

十一、和数字相关(14)

数据类型(4):bool、int、float、complex

进制转换(3):bin、oct、hex

数学运算(7):abs、divmod、round、powsum、min、max

数据类型(4)

bool:  bool() 函数用于将给定参数转换为布尔类型,如果没有参数,返回 False。

 int():  int() 函数用于将一个字符串会数字转换为整型。

float():   float() 函数用于将整数和字符串转换成浮点数。

complex():  函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。

l = complex(1,2)
print(l)  # (1+2j)
l = complex(1)
print(l)  # (1+0j)
l = complex('1+6j') #注意:这个地方在"+"号两边不能有空格,也就是不能写成"1 + 6j",应该是"1+6j",否则会报错
print(l)  # (1+6j)

进制转换:bin、oct、hex、

bin:  bin() 返回一个整数 int 或者长整数 long int 的二进制表示

oct:  oct() 函数将一个整数转换成八进制字符串。

hex: hex() 函数用于将十进制整数转换成十六进制整数。

数字运算:abs、divmod、round、pow

abs:函数返回数字的绝对值。

  abs( x )

print(abs(-5))  #5

divmod:取商余,把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。

  divmod(a, b)

ret = divmod(10,2) 
print(divmod(10,2))
#商余 print(ret) # (5, 0) 
ret = divmod(3,2)
print(ret) # (1, 1)
ret = divmod(7,2)
print(ret) # (3, 1)

在 python 2.3 版本之前不允许处理复数。

round:小数点精确,方法返回浮点数x的四舍五入值。

  round( x ,n )

print(round(3.14159,2))  # 3.14

pow:幂运算,返回 xy(x的y次方) 的值。

print(pow(2,3.5))   # 11.313708498984761
print(pow(3,2))    # 9  x**y
print(pow(2,3,2))  # 0 x**y%z
print(pow(2,3,3))  # 2  x**y%z

sum:求和

  sum(iterable, start)

  iterable -- 可迭代对象,如列表

  start -- 指定相加的参数,如果没有设置这个值,默认为0。

print(sum([1,2,3,4,5,6],-2))  # 19
print(sum(range(100)))  # 4950

min:计算最小值(返回给定参数的最小值,参数可以为序列)

  min(iterable,key,default)
  min(*args, key=None)
print(min([1,4,0,9,6]))  # 0
print(min([],default=0))  # 0
print(min([-9,1,23,5],key=abs))#匿名函数  取绝对值的最小值# 1
print(min({'z':1,'a':2}))  #ascll码的 a

max:计算最大值

  max(iterable,key,defult)
  max(*args,key,defult)
t = (-25,1,3,6,8)
print(max(t))  # 8
print(max(t,key = abs))  # -25
print(max((),default=100))  # 100

十二、和数据结构相关(24)

  列表(2):list、tuple       相关内置函数(2):reversed、slice 

    字符串(9):str、format、bytes、bytearray、memoryview、ord、chr、ascii、repr

列表:

  list:用于将元组转换为列表。

  list -- 要转换为列表的元组。

li = (123, 'xyz', 'zara', 'abc')
li2 = list(li)
print(li2)  # [123, 'xyz', 'zara', 'abc']

 tuple:将列表转换为元组

print(tuple([1, 2, 3, 4]))  # (1, 2, 3, 4)
print(tuple({1: 2, 3: 4}) ) # 针对字典 会返回字典的key组成的tuple  # (1, 3)
print(tuple((1, 2, 3, 4)))  # 元组会返回元组自身  # (1, 2, 3, 4)

  reversed:用于反向列表中元素。

  参数:序列    返回值:反序迭代器

l = [3,4,2,5,7,1,5]       #
ret = reversed(l)
print(ret)  # 迭代器  需要list调用(next、for)
print(list(ret))  # [5, 1, 7, 5, 2, 4, 3]
print(list(ret))  # [] reversed()之后的iterator只在第一次遍历时返回值。
l.reverse()
print(l) # [5, 1, 7, 5, 2, 4, 3]
返回值不同:
  reversed:
    返回迭代器
    不改变原来的列表,生成一个新的序列迭代器
  reverse:
    返回None
    是在原来的列表的基础上修改的
补充从迭代器取值‘
1、list()
2、next
3、for
 

  slice:切片对象,主要用在切片操作函数里的参数传递。

  slice(stop)
  slice(start, stop[, step])

  start -- 起始位置

  stop -- 结束位置

  step -- 间距

l = (1,2,23,213,5612,342,43)
sli = slice(1,5,2)   #实现了切片的函数
print(l[sli])  # (2, 213)
#  l[1:5:2]  语法糖
 

字符串(9):str、formatbytes、bytearray、memoryview、ord、chr、ascii、repr

str:将对象转化为适于人阅读的形式。

format

说明:

  1. 函数功能将一个数值进行格式化显示。

  2. 如果参数format_spec未提供,则和调用str(value)效果相同,转换成字符串格式化。

print(format('test','<20'))  # test                左对齐
print(format('test','>20'))  #                 test右对齐
print(format('test','^20'))  #         test        居中

bytes() 

     bytes(s,encoding='utf-8')

bytes()  #字节  用于网络编程的时候
#网络编程的时候:能在网络上传递的必须是字节
ret = bytes('明天,你好,希翼',encoding='utf-8')
#中间是网络传输的过程
print(ret.decode(encoding='utf-8'))
 bytearry:返回一个新字节数组。这个数组里的元素是可变的,并且每    个元素的值范围: 0 <= x < 256。
  (bytes(s,encoding='utf-8')
ret = bytearray('alex',encoding='utf-8')
# 对比较长的字符串做修改的时候,指定某一处进行修改,不会改变这个bytearray的内存
print(id(ret))  #  36669568(随机)
print(ret[0])  # 97
ret[0] = 65
print(ret)  # bytearray(b'Alex')
print(id(ret))  # 36669568(内存地址与上面的一样)
memoryview:返回给定参数的内存查看对象
  内存查看对象,是指对支持缓冲区协议的数据进行包装,在不需要复制对象基础上允许Python代码访问。

      只能对bytes类型起作用
memoryview
    只能对bytes类型起作用
ret = memoryview(bytes('你好',encoding='utf-8'))
print(ret)  #<memory at 0x00000000024CF048>
print(len(ret))  # 6
print(ret[:3])  # <memory at 0x00000000024CF108>
print(bytes(ret[:3]).decode('utf-8'))  # decode转译  # 你
print(bytes(ret[3:]).decode('utf-8'))  #

ord   字符按照unicode转数字

chr   数字按照unicode转字符

print(ord('a'))  # 97
print(chr(97))  # a

ascii   只要是ascii码中的内容,就打印出来,不是就转换成

print(ascii('a'))  # 'a'
print(ascii(1))  # 1
repr() 用于%r格式化输出(将对象转化为供解释器读取的形式。)
print(repr(1))  # 1
print(repr('1'))  # '1'

frozenset   不可变集合(返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。)

和数据结构相关

  相关内置函数(8)lenenumerate、all、any、zip、filter、map、sorted

len()

   len() 方法返回对象(字符、列表、元组等)长度或项目个数。

enumerate(), 枚举

l = ['笔记本','phone','apple','banana']
for i in enumerate(l,1):
    print(i[0],i[1])
# 1 笔记本
# 2 phone
# 3 apple
# 4 banana

all  返回bool值(接收可迭代对象,只有有一个False,就为假)

any  判断是否有bool值为True的值,有真就为真

print(all([1,2,3,4,0]))  # False
print(all([1,2,3,4]))  # True
print(all([1,2,3,None]))  # False
print(all([1,2,3,'']))  # False

print(any([True,None,False]))  # True
print(any([False,None,False]))  # False

zip()  拉链函数,语法为:zip(iterable,iterable...),将可迭代的对象作为参数,将对象中对应的元  素打包成一个个元组,然后返回由这些元组组成的列表迭代器。如果各个迭代器的元素个数不一致,则返回  列表长度与最短的对象相同。

以短的为基准,一一对应
print(list(zip([0,1,2,3,4],[5,6,7,8],['a','b'])))  # [(0, 5, 'a'), (1, 6, 'b')]

filter(  过滤函数(就是有一个可迭代对象,想要,一个新的内容集,是从原可迭代对象中筛选出来的

新的内容少于等于原内容的时候,才能用到filter

# 筛选大于10的数
def is_odd(x):
    if x>10:
        return True
ret = filter(is_odd,[1,4,6,7,9,12,17]) # 为迭代器
print(list(ret))  # [12, 17]

# 筛选整除2的数
def is_odd(x):
    if x%2 == 0:
        return True
ret = filter(is_odd,[1,4,6,7,9,12,17])
print(list(ret))  # [4, 6, 12]

# 删除偶数,保留奇数
def is_odd(x):
    if x%2 == 1:
        return True
ret = filter(is_odd,[1,4,6,7,9,12,17])
print(list(ret))  # [1, 7, 9, 17]

# 删除None或者空字符串
l = ['test', None, '', 'str', '  ', 'END']
def func(x):
    return x and x.strip()
ret = filter(func,l)
print(list(ret)) # ['test', 'str', 'END']
#筛选出1-100中平方根是整数的数
import math
def is_sqr(x):
    return math.sqrt(x) % 1 == 0
ret = filter(is_sqr,range(1,101))
print(list(ret))   # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

map

  应用于每一个可迭代的项,返回的是一个结果list。如果有其他的可迭代参数传进来,map函数则会把每一个参数都以相应的处理函数进行迭代处理。map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

  新的内容的个数等于原内容的个数

ret = map(abs,[-1,-5,6,-7])  # abs(-1)=1  abs(-5)=5
print(list(ret))  # [1, 5, 6, 7]
filter 与 map总结
  参数很相近:
    都是一个函数名+可迭代对象
  且返回值页很相近:
    都是返回可迭代对象
  区别
    filter 是做筛选的,结果还是原来就在可迭代对象中的项
    map是对可迭代对象中的每一项做操作的,结果不一定是原来就在可迭代对象中的项

例子:

有一个list, L = [1,2,3,4,5,6,7,8],我们要将f(x)=x^2作用于这个list上,那么我们可以使用map函数处理

def func(x):
    return x*x
ret = map(func,[1,2,3,4,5,6,7,8])
print(list(ret))  # [1, 4, 9, 16, 25, 36, 49, 64]

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

参数说明:

  iterable:是可迭代类型;
  key:传入一个函数名,函数的参数是可迭代类型中的每一项,根据函数的返回值大小排序;
  reverse:排序规则. reverse = True  降序 或者 reverse = False 升序,有默认值。
  返回值:有序列表

对List、Dict进行排序,Python提供了两个方法
对给定的List L进行排序,
  方法1.用List的成员函数sort进行排序,在本地进行排序,不返回副本
  方法2.用built-in函数sorted进行排序(从2.4开始),返回副本,原始输入不变

sort 是直接修原列表的顺序 , 节省内存
sorted 是生成一个新列表 , 不改变原列表
l1 = [1,3,5,-2,-4,-6]
l2 = sorted(l1,key = abs)   #按绝对值排序
print(l1)  # [1, 3, 5, -2, -4, -6]
print(l2)  # [1, -2, 3, -4, 5, -6]

l = [[1,2],[3,4,5,6],(7,),'123']  #按每个元素的len排序
print(sorted(l,key=len))  # [(7,), [1, 2], '123', [3, 4, 5, 6]]

 数据集合(3):字典(1)dict 集合:(2)set、frozenset

 字典:dict
    用于创建一个字典。
集合:
  set:创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
 
x = set('runoob')
y = set('google')
print(x&y)  #  {'o'}  交集
print(x|y)  # {'g', 'r', 'u', 'n', 'l', 'e', 'b', 'o'}  并集
print(x-y)  # {'g', 'r', 'u', 'n', 'l', 'e', 'b', 'o'}  差集

frozenset:

    返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。

    返回新的 frozenset 对象,如果不提供任何参数,默认会生成空集合。
 

匿名函数

目前在python语言中常见的一句话代码有:三元运算、各种表达式(如,列表表达式和生成器表达式)及匿名函数,也称为lambda表达式

  匿名函数:为了解决那些功能很简单的需求而设计的一句话函数

#普通
def calc(n):
    return n**n
print(calc(10))
 
#匿名函数
calc = lambda n:n**n
print(calc(10))

从上实例可以看出匿名函数的调用方式和普通函数一样,通过传参实现函数的调用,其格式可以总结为:函数名=lambda 参数1,参数2...:返回值;另一方面匿名函数可以实现真正的匿名。主要的表现在和其他功能函数合作的时候,如下例:

函数名 = lambda 参数 :返回值

#参数可以有多个,用逗号隔开
#匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
#返回值和正常的函数一样可以是任意数据类型
def add(x,y):
    return x+y

add = lambda x,y:x+y
上面是匿名函数的函数用法。除此之外,匿名函数也不是浪得虚名,它真的可以匿名。在和其他功能函数合作的时候
l=[3,2,100,999,213,1111,31121,333] print(max(l)) dic={'k1':10,'k2':100,'k3':30} print(max(dic)) print(dic[max(dic,key=lambda k:dic[k])])
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)

输出
1
25
49
16
64
dic={'k1':10,'k2':100,'k3':30}
# print(max(dic.values()))
# print(max(dic))
print(max(dic,key=lambda k:dic[k]))
def func(x):
    return x*x
ret = map(lambda x:x*x,[1,2,3,4,5,6,7,8])
print(list(ret))


def func(num): return num>99 and num<1000 ret = filter(lambda num: num>99 and num<1000,[1,4,6,823,67,23]) print(list(ret))

面试题:

(1)现有两个元组(('a'),('b')),(('c'),('d')),请使用python中匿名函数生成列表[{'a':'c'},{'b':'d'}]

#匿名函数形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
ret=map(lambda n:{n[0]:n[1]},zip(l1,l2))
print(list(ret))
#列表表达式形式:
l1=(('a'),('b'))
l2=(('c'),('d'))
print([{n[0]:n[1]} for n in zip(l1,l2)])

(2)计算运算结果

d = lambda p:p*2
t = lambda p:p*3
x = 2
x = d(x)
x = t(x)
x = d(x)
print x  # 24

(3)以下代码的输出是什么?请给出答案并解释。

def multipliers():
    return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
#解释:
  函数返回值为一个列表表达式,经过4次循环结果为包含四个lambda函数的列表,
由于函数未被调用,循环中的i值未被写入函数,经过多次替代,循环结束后i值为3,
故结果为:6,6,6,6

请修改multipliers的定义来产生期望的结果(0,2,4,6)。

def multipliers():
    returnlambda x:i*x for i in range(4))         #返回一个生成器表达式
print([m(2) for m in multipliers()])
原文地址:https://www.cnblogs.com/jassin-du/p/7810678.html