从元组列表中获取最小最大值

Arn*_*OVA 3 python sorting tuples list python-3.x

我有一个元组列表,对应于某些点的 ( x,y)坐标(可以是 8 到数百个点):

mylist = [(x0,y0), (x1,y1), ..., (xn,yn)]
Run Code Online (Sandbox Code Playgroud)

我想获得xy坐标的最小值和最大值(所有x 的最小值,无论它们,等等)。就是优化比例,把点画成矩形区域。

所以我有两个解决方案:

  • 第一种解决方案:创建两个带有坐标[foo[0] for foo in mylist]且相同的列表foo[1]。然后我可以轻松获得最小值和最大值。但是我必须创建列表(为了不进行两次理解,一次为一分钟,一次为最大值)。

  • 第二种解决方案:对列表进行两次排序,一次根据第一个坐标,然后到第二个坐标,每次获取第一个和最后一个值。内存占用少,但需要排序。

最好的解决方案是什么?

Ch3*_*teR 5

你可以zip在这里使用。

In [1]: a=[(1,2),(3,4),(5,6)]

In [2]: x,y=zip(*a)

In [3]: x
Out[3]: (1, 3, 5)

In [4]: y
Out[4]: (2, 4, 6)

In [5]: min(x),max(x)
Out[5]: (1, 5)  #1 in min and 5 is max in x

In [6]: min(y),max(y)
Out[6]: (2, 6)   #2 is min and 5 is max in y
Run Code Online (Sandbox Code Playgroud)

timeit分析google colab

%timeit minmax(z) #ch3ster's answer
1 loop, best of 3: 546 ms per loop

%timeit  minmax1(z) #CDJB's answer
1 loop, best of 3: 1.22 s per loop

%timeit minmax2(z) #Mihai Alexandru-Ionut's answer
1 loop, best of 3: 749 ms per loop

%timeit minmax3(z) #Yevhen Kuzmovych's answer
1 loop, best of 3: 1.59 s per loop
Run Code Online (Sandbox Code Playgroud)

编辑:如果我们set在这里使用,我们仍然可以减少执行时间。

In [24]: def minmax(a):
    ...:     x=set()
    ...:     y=set()
    ...:     for i,j in a:
    ...:         x.add(i)
    ...:         y.add(j)
    ...:     return max(x),min(x),max(y),min(y)
Run Code Online (Sandbox Code Playgroud)

元组列表(大小为 300 万或 300 万)用于基准测试。

z=[(randint(0,10),randint(0,10)) for _ in range(3000000)]
Run Code Online (Sandbox Code Playgroud)

timeit 在 python 3.7 和 windows 10 中分析本次编辑(2 月 4 日上午 12:28)。

In [25]: timeit minmax(z) #Ch3steR's set answer.
384 ms ± 26.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [44]: timeit minmax1(z) #Ch3steR's zip answer.
626 ms ± 3.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [39]: timeit minmax2(z) #CDJB's answer max with lambda
1.18 s ± 25.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [40]: timeit minmax3(z) #Mihai Alexandru-Ionut's answer max with itemgetter
739 ms ± 42.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [41]: timeit minmax4(z) #Yevhen Kuzmovych's answer with updating max and min while iterating
1.97 s ± 42.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Run Code Online (Sandbox Code Playgroud)

Ch3steR 的设定答案 < Ch3steR 的 zip 答案 < Mihai Alexandru-Ionut 的答案最大值和最小值与 itemgetter < CDJB 的答案最大值和最小值与 lambda < Yevhen Kuzmovych 的答案,在迭代时更新最大值和最小值

0<= x,y <=1000000 List 用于基准测试时。

x=[(randint(0,1000000),randint(0,1000000)) for _ in range(3000000)]
Run Code Online (Sandbox Code Playgroud)

timeit 分析。

In [48]: timeit minmax(x) #Ch3steR's set answer.
1.75 s ± 92.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [49]: timeit minmax1(x) #Ch3steR's zip answer.
753 ms ± 31.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [51]: timeit minmax2(x) #CDJB's answer max with lambda
1.29 s ± 115 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [52]: timeit minmax3(x) #Mihai Alexandru-Ionut's answer max with itemgetter
794 ms ± 35.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [53]: timeit minmax4(x) #Yevhen Kuzmovych's answer with updating max and min while iterating
2.3 s ± 164 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Run Code Online (Sandbox Code Playgroud)

笔记 :

Ch3steR 的集合是有效的,0< x,y < 10但当0< x,y <1000000它平均为1.7s

我强烈建议使用Ch3steR's answer with zipMihai Alexandru-Ionut's answer max and min with itemgetter when 0< x,y < 1000000

  • @Ch3steR 你=太棒了 (2认同)

Mih*_*nut 5

你可以使用maxwithitemgetter()函数,我认为它是与 相比的more有效解决方案lambda,符合这个答案。

from operator import itemgetter
max_x = max(mylist,key=itemgetter(0))[0]
Run Code Online (Sandbox Code Playgroud)