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

时间:2017-09-26 18:28:15

标签: python python-3.x

在(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)]}

4 个答案:

答案 0 :(得分:4)

基本思路:获取所有x值和所有y值的列表,然后获取每个单独列表的最大值。

import itertools
x,y = zip(*itertools.chain(*roi.values()))
print(max(x),max(y))

说明:roi.values()从键值对中获取所有值,然后itertools.chain(*...)将2元组的列表组合成1个列表,最后zip(*...)反转列表,以便而不是2个元组的k列表,你有2个k元组,你可以得到max

答案 1 :(得分:4)

我个人会在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

答案 2 :(得分:3)

试试这个:

x = 0
y = 0

for key in roi:

    foo = roi[key]

    for item in foo:

        if item[0] > x:
            x = item[0]

        if item[1] > y:
            y = item[1]

这个程序循环遍历字典的每个键。它循环遍历每个元组并比较' x'并且' y'值。

我假设每个元组中的第一个元素是' x'第二个元素是' y'。

答案 3 :(得分:2)

class Lamp extends React.component {
     constructor(){
       super();
       this.state = {
       active: false
       };
     }
    toggleActive() {
       this.setState({ active: !this.state.active });
    }
    render() {
         return (
                <div
                style={{ backgroundColor: this.state.active ? 
                this.props.color : "" }}>lampada
                <button onclick={() => this.toggleActive()}>on/off</button>
                </div>
         );
   }
}
React.render(<Lamp color="green" />, document.body);