匿名函数 lambda 表达式
内建函数 id,hash,type,input,print,len
float,int,hex,oct,bool,list,tuple,dict,set
isinstance,issubclass
abs,max,min,round,pow,range,divmod,sum
chr,ord,str,repr,ascii
sorted,reversed,enumerate,iter,next
zip,all,any,filter,map

匿名函数


  • 匿名函数:没有函数名的函数
  • 使用 lambda 关键字构造匿名函数:lambda [参数列表]:表达式
  • Python 主要提供了这么几个函数:map()、filter()reduce(),通常结合匿名函数 lambda 一起使用(可参看如下章节map filter
# 举例
lambda x,y: x+y

# 等效于
def add(x,y):
    return x+y

# lambda函数调用
(lambda x,y: x+y)(4, 5)
--------------------------
9

lambda 表达式

  1. 参数列表不需要小括号,无参数的话就不写参数
  2. 冒号用来分隔参数列表和表达式
  3. 不需要使用return, 表达式的值就是匿名函数的值,表达式中不能出现等号
  4. 返回值为None必须写明
  5. 表达式只能单行表达式
  6. 往往用在高阶函数传参时,使用 lambda 表达式可以简化代码

扩展阅读:Python 之父为什么嫌弃 lambda 匿名函数?

  • lambda函数的缺陷
    当前的 lambda 函数有一个最大的问题,即只支持单行表达式,无法实现丰富的功能,例如无法在函数创建时使用语句(statement),无法使用 if-else 的判断条件,也无法使用 try-except 的异常捕获机制等。这极大地限制了它的能力,导致了它被人诟病为“残疾的”
  • lambda 函数通常的用法是结合 map()、reduce()、filter()、sorted() 等函数一起使用,这些函数的共性是:都可以接收其它函数作为参数
my_list = [3, 1, 5, 4, 10]

# 元素全加1,结果:[4, 2, 6, 5, 11]
list(map(lambda i:i+1, my_list)) 

# 过滤小于10的元素,结果:[3, 1, 5, 4]
list(filter(lambda i:i<10, my_list)) 

# 元素累加,结果:33
from functools import reduce
reduce(lambda i,j:i+j, my_list, 10)

# 字典按值排序,结果:[('b', 1), ('a', 3), ('d', 4), ('c', 5)]
my_dict = {'a':3, 'b':1, 'c':5, 'd':4}
sorted(my_dict.items(), key=lambda item:item[1])

匿名函数的参数和表达式

# 无参数函数且返回值为None
(lambda : None)()

# 带缺省值的函数
(lambda x,y=3: x+y)(5)
(lambda x,y=3: x+y)(5,2)

# keyword-only参数
(lambda x,*,y=3: x+y)(5)
(lambda x,*,y=3: x+y)(5,y=2)

# 可变参数
(lambda *args: [x+1 for x in args])(1,2,3)
(lambda *args: {x+1 for x in args})(*range(5))
(lambda *args: (x+1 for x in args))(*range(5))
  • 排序问题
    例子:对 [2, 1, '1', 'a'],list 中若为字符,按 ascii 值进行比较
l = [2, 1, '1', 'a']
l.sort(key=lambda x: ord(x) if isinstance(x, str) else x)
print(l)
----------------------------------------------------------
[1, 2, '1', 'a']

**注意:**这里说的内建函数,有的其实是类,习惯称为内建函数而已,具体可参考官方 py.chm

id hash type input print len


  1. 标识 id
    • 返回对象的唯一标识,Cpython 返回内存地址
    • 返回相同的标识则是同一个对象
    • 理解is==的区别
a = 1
b = 1
c = [1, 2]
d = [1, 2]
print(a==b, c==d)
print(id(a), id(b),a is b, id(c), id(d), c is d)
------------------------------------------------
True True
140721402146560 140721402146560 True 2813380931720 2813380898632 False

==is 运算符都用于比较两个对象的值。== 运算符用于比较两个对象的是否相等。这意味着它检查对象的内容是否相同,而不是它们是否是同一个对象;is 运算符用于比较两个对象是否是同一个对象,这意味着它检查对象的身份是否相同,而不是它们的内容是否相同。

  1. 关于 id 的一些扩展
# 看下面的例子
i1 = 1
i2 = 1
i3 = 257
i4 = 257
s1 = 'abc'
s2 = 'abc'
print(id(i1)==id(i2), id(i3)==id(i4), id(s1)==id(s2))
------------------------------------------------------
True False True

当 int 是 [-5, 256] 这些小整数时,它会被定义在了对象池里。所以当引用小整数时会自动引用整数对象池里的对象。
string 对象也是不可变对象, python 有个 intern 机制, 简单说就是维护一个字典, 这个字典维护已经创建字符串 (key) 和它的字符串对象的地址(value), 每次创建字符串对象都会和这个字典比较, 没有就创建, 重复了就用指针进行引用就可以了。

【以下内容来自ChatGPT】

  • 单例对象
    在Python中,为了提高性能和节省内存,对于一些简单的对象(如整数、浮点数、空字符串、布尔值、None等),Python会进行缓存和复用。这些对象被称为“单例对象”(Singleton Objects)。
    例如,Python中的整数对象,在程序启动时就会被预先缓存。当程序需要使用一个整数对象时,Python会先查找缓存中是否已经存在这个整数对象,如果存在,则直接返回缓存中的对象,否则会创建一个新的整数对象并加入缓存中,然后返回这个对象的引用。这样可以避免频繁地创建和销毁对象,提高程序的性能和效率。
    Python中还有一些其他的单例对象,如None、True、False、空字符串""等等。对于这些对象,Python同样会进行缓存和复用,以提高程序的性能和节省内存。
    除以上常见单例对象外,Python还有一些其他单例对象:
  1. Ellipsis:省略号对象
print(...)
print(type(...))
a = ...
b = ...
print(a is b)
#############输出结果############
Ellipsis
<class 'ellipsis'>
True
  1. NotImplemented:表示未实现的操作的对象,通常情况下,它用在抽象基类中,用于指示子类需要实现特定的方法
  • inter 机制
    Python的解释器中有一个机制,叫做"内部化"(interning)或者"内部缓存"(internal caching),可以将一些不可变的对象(如字符串、数字、元组等)缓存起来,以减少重复创建这些对象的开销。
    当Python解释器遇到字符串字面值时,会先在缓存池中查找该字符串是否已经存在,如果存在,则直接返回已有对象的引用;如果不存在,则创建一个新的字符串对象,并将其添加到缓存池中,然后返回新创建对象的引用。
    这种机制可以减少内存占用,提高字符串比较操作的速度。不过需要注意的是,这个机制只对长度小于等于255的字符串起作用,因为长度大于255的字符串会被分配到堆内存中,无法进行缓存。另外,不是所有的Python实现都会实现这种机制,具体实现也可能因版本而异。
    需要注意的是,这个机制只对不可变对象起作用,对于可变对象(如列表、字典、集合等)并不适用。

更多可参考python的内存管理和垃圾回收

  1. 哈希 hash
    • 返回一个对象的哈希值
    • 幂等性:同一次运行,对同一对象求 hash 得到的值是相同的
    • 可以用 hash 函数判断对象是否可哈希 hashable
    • 关于哈希 hash 的本质可参考面向对象进阶:魔术方法
print(hash(1))
print(hash("abc"))
print(hash("abc"))
-------------------
1
1574483839575160150
1574483839575160150

hash([])
-------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-4c7351eba020> in <module>()
----> 1 hash([])

TypeError: unhashable type: 'list'
  1. 类型 type
    • 返回对象的类型
print(type(1),type('abc'),type(type),type(list),type([]))
-------------------------------------------------------------
<class 'int'> <class 'str'> <class 'type'> <class 'type'> <class 'list'>
  1. 输入 input([prompt])
    • 接收用户输入,返回一个字符串
  2. 打印 print(*objects, sep='', end='\n', file=sys.stdout, flush=False)
    • 打印输出
    • 默认用空格分隔、换行结尾,输出到控制台
  3. 对象长度 len

float int hex oct bool list tuple dict及set


print(hex(255))
print(bool(0),bool(None),bool([]),bool(tuple()),bool(set()),bool({}),bool(''))
----------------------------------------------------------------------------------
0xff
False False False False False False False

isinstance和issubclass


  1. isinstance(obj,class_or_tuple)
  • 判断对象是否属于某种类型或者元组中列出的某种类型
  • isinstance(True,int):bool 类型属于 int 类型
  1. issubclass(cls,class_or_tuple)
  • 判断类型 cls 是否是某种类型的子类或元组中列出的某个类型的子类
  • issubclass(bool,int):bool 类型是 int 类型的子类
print(isinstance(True,int), isinstance([1,2],(list,tuple)))
print(issubclass(bool,int),issubclass(int,object))
------------------------------------------------------
True True
True True

abs max min round pow range divmod及sum


  1. 绝对值 abs(x)
  2. 最大值 max() 最小值 min()
  3. round(x) 四舍六入五取偶
  4. pow(x,y) 等价于 x**y
  5. range
    • range(stop) 从 0 到 stop-1 的可迭代对象
    • range(start,stop[,step]) 从 start 到 stop-1, 步长为 step 的可迭代对象
  6. divmod(x,y)
    • 返回一个元组,等价于 tuple(x//y,x%y)
  7. sum(iterable[,start])
    • 对可迭代对象所有元素求和
    • start 为基数
sum(range(10)),sum(range(10),100)
---------------------------------
(45, 145)

chr ord str repr及ascii


  1. chr(i) 给一个一定范围的整数返回对应的字符
  2. ord(c) 返回字符对应的整数,返回的是 Unicode
print(chr(97))
print(ord('a'))

# 所有数字
all_nums_alphabet = ''.join([str(i) for i in range(10)])
# 所有大写字母
for i in range(65,91):
    all_nums_alphabet += chr(i)
# 所有小写字母
for i in range(97,123):
    all_nums_alphabet += chr(i)
print(all_nums_alapha)
----------------------------------------------------------------
a
97
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
  1. str()
  2. repr()
  3. ascii()

sorted reversed enumerate iter及next


  1. sorted(iterable[,key][,reverse]) 排序
    • 立即返回一个新的列表,默认升序
  2. reversed(seq)
    • 返回一个翻转元素的迭代器
  3. enumerate(seq, start=0)
    • 迭代一个序列,返回索引数字和元素构成的二元组
    • start 表示索引开始的数字,默认 0
    • 返回一个迭代器
list(enumerate('abcd'))
list(enumerate('abcd',1))
list(enumerate({'a':1,'b':2}))
----------------------------
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
[(0, 'a'), (1, 'b')]
  1. iter(iterable)
    • 将一个可迭代对象封装成一个迭代器
from collections.abc import Iterator
print(isinstance([1,2,3],Iterator))
print(isinstance(iter([1,2,3]),Iterator))
------------------------------------------
False
True
  1. next(iterator[,default])
    • 对迭代器取出下一个元素, 可用 next 函数调用对象一定是迭代器
    • 如果元素全部取出,再次调用 next 则会抛 StopIteration 异常

zip all any filter及map


  1. zip(*iterables)
    • 多个可迭代对象合并在一起,返回一个迭代器
    • 将每次从不同对象中取到元素合并成一个元组
z = zip(range(10),'abc')
print(next(z))
print(next(z))
print(next(z))
------------------------
(0, 'a')
(1, 'b')
(2, 'c')

z = zip(range(10),'abc','defg')
list(z)
-------------------------
[(0, 'a', 'd'), (1, 'b', 'e'), (2, 'c', 'f')]

区别于itertools.zip_longest

  1. zip 二元组方式构造字典
dict((['a',1],)) # 二元组
dict(zip('abc', range(1, 10)))
-------------------------
{'a': 1}
{'a': '1', 'b': '2', 'c': '3'}
  1. all(iterable)
    • 可迭代对象所有元素都要等效为 True,或空的可迭代对象,all 函数返回为 True
    • 只要可迭代对象有一个元素等效为 Flase,all 函数返回为 False
  2. any(iterable)
    • 可迭代对象任意一个元素等效为 True,any 函数返回为 True
    • 空可迭代对象或所有元素都等效为 False,all 函数返回为 False
  3. 过滤 filter
    • filter(function,iterable),通俗理解就是将可迭代对象值一个个拿出来,不满足 function 条件的过滤掉
    • 对可迭代对象遍历,返回一个迭代器
    • function 参数是一个带参函数,且返回值是 bool 类型或等效布尔值
    • function 参数如果是 None,可迭代对象的每个元素自身等效布尔值
list(filter(lambda x: x%2==0,range(10))) # 取偶数
list(filter(None,range(10))) # 0 等效为False
-----------------------------------------
[0, 2, 4, 6, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. 映射 map
    • map(function,*iterable),通俗理解就是可迭代对象一个个值拿出来,按照 function 进行映射x->y的过程
    • 多个可迭代对象的元素,按照指定函数进行映射
    • 返回一个迭代器
list(map(lambda x:x**2,range(5)))
list(map(lambda x,y:x+y,[1,2,3],[9,10,11,12]))
---------------------------------------------------
[0, 1, 4, 9, 16]
[10, 12, 14]
  1. 用 map 构造 dict
dict(map(lambda x,y:(x,y),'abc',range(10)))
-------------------------------------------
{'a': 0, 'b': 1, 'c': 2}

扩展阅读


参考