本帖最后由 Brick_Porter 于 2022-8-31 17:39 编辑
因为这是map函数和max函数共同作用的结果。不太清楚你对Python了解到什么程度了,所以我尽量用通俗的语言来解释。
先来看真正用来比较大小的max函数,它有两种用法:
1. max(iterable, *[, default=obj, key=func]) -> value
这里的iterable就类似我们平时使用的列表、元组等数据,如果只传入
一个列表或者元组,就返回其中的最大值。如果还设置了default,那么当iterable为空的时候就返回default的值。例如:
>>> max([1, 2, 3]) # 只传入一个列表
3
>>> max((233, 120, 99)) # 只传入一个元组
233
>>> max([], default=666) # 传入一个空列表,并且设置默认返回的值
666
最后一个参数key的值是一个函数,用来自定义筛选标准,不是我们今天讨论的重点,不做过多展开。
2. max(arg1, arg2, *args, *[, key=func]) -> value
第二种用法是一次传入
多个参数(两个及以上),此时max会找出这些参数中的最大值,例如:
>>> max(1, 2) # 传入两个参数
2
>>> max(1, 5, 3) # 传入三个参数
5
>>> max([1, 2], [4, 5, 6], [9, 1]) # 注意这种情况,传入的参数是3个列表
[9, 1]
特别注意最后一种情况,当传入的参数是多个iterable的时候max会
把它们对齐然后依次i比较,也就是类似这样:
然后从索引为0处开始比较这三个列表,索引为0处的三个值分别是1、4、9,其中9最大,所以此时max直接返回[9, 1],这里请注意max([1, 2], [4, 5, 6], [9, 1])其实是通过列表中的具体数字来比较三个列表的大小,因为传入的参数是列表所以返回的最大值也是列表类型。
list(map(max, [1, 3, 5], [2, 2, 2], [0, 3, 9, 8]))的返回值是[2, 3, 9],这个结果很有迷惑性,我们很难第一时间判断到底是哪种用法。
其实此处是max的第一种用法,因为如果是按照第二种方法,虽然max会对齐三个列表然后比较大小,但因为传入的都是列表类型,所以结果也应该是列表,第一轮比较(1, 2, 0)之后结果很明朗,2最大,所以应该返回列表[2, 2, 2],但结果却是[2, 3, 9],所以显然不是第二种用法。
但是第一种max用法并不会对齐三个列表,似乎进入死胡同了。但我开头说了,这里还有一个重要的“函数”map,其实负责对齐[1, 3, 5]、[2, 2, 2]、[0, 3, 9, 8]这三个列表的是它!
map(func, *iterables),我们重点来看看map的第二个参数。
当第二个参数是
一个列表或者元组的时候map会把这个列表或元组的所有元素都给第一个func函数处理;
但是当第二个参数是多个类似列表的数据时,map会先把它们对齐,然后把对齐的元素传给第一个参数func函数。
而我们的代码[1, 3, 5], [2, 2, 2], [0, 3, 9, 8]显然符合第二种情况,于是乎它们被对齐为(1, 2, 0), (3, 2, 3), (5, 2, 9),然后这三个元组分别传给max函数,于是max分别返回2、3、9,最后由list转为列表,所以结果就变成了[2, 3, 9]。
综上所述,max和map都会对传入的多个iterable对齐,但map先对输入的参数做了对齐处理,然后才把对齐的结果传给max函数,因此结果才会是[2, 3, 9]。
最后,关于对齐我建议你学习zip函数,它具有对齐多个iterable的功能。