嵌套列表上的 min/max 函数如何工作?
Posted
技术标签:
【中文标题】嵌套列表上的 min/max 函数如何工作?【英文标题】:How does the min/max function on a nested list work? 【发布时间】:2016-03-07 03:06:24 【问题描述】:假设有一个嵌套列表,例如:
my_list = [[1, 2, 21], [1, 3], [1, 2]]
当函数min()
被调用时:
min(my_list)
收到的输出是
[1, 2]
为什么以及它是如何工作的?它有哪些用例?
【问题讨论】:
【参考方案1】:如何在 Python 中比较列表和其他序列?
Python 中的列表(和其他序列)在lexicographically 中进行比较,而不是基于任何其他参数。
序列对象可以与具有相同序列类型的其他对象进行比较。比较使用字典顺序:首先比较前两项,如果它们不同,则确定比较的结果;如果它们相等,则比较接下来的两项,以此类推,直到任一序列用完为止。
什么是字典排序?
来自lexicographic sorting 上的***页面
字典顺序或字典顺序(也称为词汇顺序、字典顺序、字母顺序或字典(al)产品)是单词的字母顺序基于其组成字母的字母顺序的方式的概括。
min
函数返回 iterable 中的最小值。所以[1,2]
的字典值是该列表中最小的。您可以使用[1,2,21]
进行检查
>>> my_list=[[1,2,21],[1,3],[1,2]]
>>> min(my_list)
[1, 2]
min
这种情况发生了什么?
my_list
上的元素明智,首先是 [1,2,21]
和 [1,3]
。现在来自文档
如果要比较的两个项目本身是相同类型的序列,则按递归地进行字典比较强>。
因此[1,1,21]
的值小于[1,3]
,因为[1,3]
的第二个元素,即3
,在字典上高于第二个元素的值[1,1,21]
,即1
。
现在比较 [1,2]
和 [1,2,21]
,并添加来自文档的另一个参考
如果一个序列是另一个序列的初始子序列,则越短的序列越小 (较小的)一个。
[1,2]
是[1,2,21]
的初始子序列。因此[1,2]
的值总体上小于[1,2,21]
的值。因此[1,2]
作为输出返回。
这可以通过使用sorted
函数来验证
>>> sorted(my_list)
[[1, 2], [1, 2, 21], [1, 3]]
如果列表有多个最小元素怎么办?
如果列表包含重复的最小元素返回第一个
>>> my_list=[[1,2],[1,2]]
>>> min(my_list)
[1, 2]
这可以使用id
函数调用来确认
>>> my_list=[[1,2],[1,2]]
>>> [id(i) for i in my_list]
[140297364849368, 140297364850160]
>>> id(min(my_list))
140297364849368
我需要做些什么来防止 min
中的字典比较?
如果所需的比较不是字典式,则可以使用key
参数(如Padraic 所述)
min
函数有一个名为key
的附加可选参数。 key
参数接受一个函数。
可选的 key 参数指定一个单参数排序函数 就像用于
list.sort()
的那样。关键参数(如果提供)必须是 以关键字形式(例如,min(a,b,c,key=func)
)。
例如,如果我们需要长度最小的元素,我们需要使用len
函数。
>>> my_list=[[1,2,21],[1,3],[1,2]]
>>> min(my_list,key=len) # Notice the key argument
[1, 3]
我们可以看到这里返回了第一个最短的元素。
如果列表是异构的怎么办?
直到 Python2
如果列表是异构的类型名称考虑排序,检查Comparisions,
除数字以外的不同类型的对象按其类型名称
排序
因此,如果您将int
和list
放在那里,您将获得最小的整数值,因为i
的值低于l
。同样'1'
将比这两者都具有更高的价值。
>>> my_list=[[1,1,21],1,'1']
>>> min(my_list)
1
Python3 及更高版本
但是,Python3 中删除了这种令人困惑的技术。它现在引发TypeError
。阅读What's new in Python 3.0
当操作数没有有意义的自然排序时,排序比较运算符(
<
、<=
、>=
、>
)会引发TypeError
异常。因此,1 < ''
、0 > None
或len <= len
等表达式不再有效,例如None < None
引发TypeError
而不是返回False
。一个推论是对异构列表进行排序不再有意义——所有元素必须相互比较。
>>> my_list=[[1,1,21],1,'1']
>>> min(my_list)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < list()
但它适用于可比较的类型,例如
>>> my_list=[1,2.0]
>>> min(my_list)
1
在这里我们可以看到list
包含float
值和int
值。但是由于float
和int
是可比较的类型,所以min
函数在这种情况下有效。
【讨论】:
对,这些解释都是我想要的,不知道是不是OP想要的。 是的,我也很满意,但有人能弄清楚它的一些用例吗?我想不出一个。我的意思是一个列表小于另一个列表真的有意义吗? python是有意支持它,还是作为实现的效果来的。 @AhsanulHaque 一个用例(我使用的)是基于索引(顺便说一下,在我的例子中是第一个元素)对嵌套列表进行排序。这些列表是使用csv
模块获得的。 AFAIK,这一定是故意的,但我还不能证实这一点。我会研究并告诉你。
@KevinGuan 是的。他们已经取消了 Py3 中的混合类型比较。见What’s New In Python 3.0
您也可以将密钥传递给 min 即 min(my_list ,key=len)
这将返回最短的列表【参考方案2】:
字典排序的一个简单用例是创建一个可排序的namedtuple
类。
from collections import namedtuple
Time = namedtuple('Time', ['hours', 'minutes', 'seconds'])
t1 = Time(hours=8, minutes=15, seconds=30)
t2 = Time(hours=8, minutes=15, seconds=0)
t3 = Time(hours=8, minutes=30, seconds=30)
t4 = Time(hours=7, minutes=15, seconds=30)
assert min(t1, t2, t3, t4) == t4
assert max(t1, t2, t3, t4) == t3
【讨论】:
【参考方案3】:两个列表按元素进行比较
即使两个列表的大小不同,两个列表也会从第一个元素开始进行比较。
现在假设列表的每个元素都已检查并且它们是相同的并且在较短的列表中没有下一个元素。然后声明较短的列表小于较长的列表。
例子:
>>> [1,2]<[1,3]
True
>>> [1,2]<[1,2,21]
True
>>> [1,3]<[1,2,21]
False
>>>[1,2,22]<[1,2,21]
False
>>>[1]<[1,2,21]
True
>>>
【讨论】:
【参考方案4】:它按元素比较列表:
>>> [1,2]<[1,3]
True
>>> [1,2]<[1,2,21]
True
>>>
【讨论】:
这真的回答了 OP 的问题吗?我认为OP知道,但是为什么以及如何?为了澄清我的评论:Python 如何比较两个列表?为什么[1,2] < [1,3]
等于True
?以上是关于嵌套列表上的 min/max 函数如何工作?的主要内容,如果未能解决你的问题,请参考以下文章