Skip to main content
 首页 » 编程设计

python之从 X-Y 元组列表的字典中获取最大 X 和 Y 的最有效方法

2025年05月04日11zengkefu

在 (x, y) 对列表的字典中,即使这些值位于不同的 (x, y) 对中,Python 3 中查找字典中最大 x 和最大 y 的最有效方法是什么?

roi =   {  '26580.BOT': [(107, 1006), 
                         (107, 973)], 
           '26580.TOP': [(107, 1008), 
                         (107, 1040), 
                         (107, 1072), 
                         (107, 1648)], 
           '26582.TOP': [(113, 977)], 
           '26685.TOP': [(105, 974)]} 

请您参考如下方法:

我个人会在 values 上使用 for 循环,因为它会对数据进行单次传递并且节省空间,但如果您更喜欢难以阅读的单行代码,总有 reduce :)

>>> import functools, itertools 
>>> def max_tuple(t1, t2): return max(t1[0],t2[0]), max(t1[1],t2[1]) 
... 
>>> ts = itertools.chain.from_iterable(roi.values()) 
>>> functools.reduce(max_tuple, ts) 
(113, 1648) 

请注意,这是节省空间的!如果您担心速度,请使用循环,或者,您可以尝试使用此替代实现来减少函数:

>>> def max_tuple2(t1, t2): 
...     (a,b), (x,y) = t1, t2 
...     return (a if a > x else x, b if b > y else y) 
... 

这对我来说测试速度要快得多,让我们做一个更大的测试字典:

>>> roi2 = {k+str(i): v*100 for k, v in roi.items() for i in range(100)} 

现在,一些测试:

>>> timeit.timeit('ts = itertools.chain.from_iterable(roi2.values()); functools.reduce(max_tuple, ts)', 'from __main__ import functools, itertools, max_tuple, roi2;', number=100) 
4.612322789034806 
>>> timeit.timeit('ts = itertools.chain.from_iterable(roi2.values()); functools.reduce(max_tuple2, ts)', 'from __main__ import functools, itertools, max_tuple2, roi2;', number=100) 
1.7526514289784245 

使用 max_tuple2 的速度是原来的两倍多。但是,如果您关心速度,请使用 naive-forloop 方法。这是@AdiC 的解决方案,经过了一些美化:

>>> def max_from_values(d): 
...     m1 = m2 = float('-inf') 
...     for tlist in d.values(): 
...         for a, b in tlist: 
...             if a > m1: 
...                 m1 = a 
...             if b > m2: 
...                 m2 = b 
...     return m1, m2 
... 
>>> max_from_values(roi2) 
(113, 1648) 

看,它比之前最快的速度快了三倍多,几乎比原来快十倍:

>>> timeit.timeit('max_from_values(roi2)', 'from __main__ import max_from_values, roi2;', number=100) 
0.4867470810422674