代码之家  ›  专栏  ›  技术社区  ›  empty Debilski

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

  •  1
  • empty Debilski  · 技术社区  · 9 年前

    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 回复  |  直到 9 年前
        1
  •  4
  •   juanpa.arrivillaga    9 年前

    values ,因为它只需对数据进行一次传递,而且节省空间,但如果您更喜欢难读的单行代码,则始终存在 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 . 但是,如果您关心速度,请使用朴素的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
  •  4
  •   Keith    9 年前

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

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

    roi.values() 从键值对中获取所有值,然后 itertools.chain(*...) 将2元组列表合并为1个列表,然后最终 zip(*...) k 在2元组中,有2个k元组,可以得到 max

        3
  •  3
  •   Adi219    9 年前

    试试这个:

    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”。

        4
  •  2
  •   pylang    9 年前
    list(map(max, zip(*[(x, y) for pair in roi.values() for x, y in pair])))
    # [113, 1648]