简体   繁体   English

在python中的成对列表中查找最小x和y值的最佳方法?

[英]Best way to find minimum x and y values in a list of pairs in python?

Given a list of data: 给定数据列表:

[[0, 0], [1, 0], [0, 1], [-1, 0], [0, -1], [1, -1], [2, 0], [1, 1], [0, 2]]

What is the fastest way in python to get the lowest X and Y in a pair. 在python中获得最低的X和Y最快的方法是什么。 In this case [-1,-1]. 在这种情况下,[-1,-1]。

Not sure it's the fastest, but it's probably the shortest and most 'pythonic': 不确定它是最快的,但可能是最短和最“ pythonic”的:

>>> map(min, zip(*data))
[-1, -1]

Update: I did some timing analysis on this, too, using a list of 10000 random sublists and 100 iterations. 更新:我也使用10000个随机子列表和100次迭代对此进行了一些时序分析。 Turns out it's a bit faster than Aशwini 's itemgetter solution, but the ordinary for -loop is still the fastest: 事实证明,它比Aशwiniitemgetter解决方案要快一点,但是普通for -loop仍然是最快的:

0.400840   min_mapminzip
0.579334   min_itemgetter
0.292459   min_loop

That was for Python 2.x... with Python 3, where zip , map etc. are iterators, it's another story: 那是针对Python 2.x ...以及Python 3,其中zipmap等是迭代器,这是另一个故事:

0.186229   min_mapminzip   # wrong result, see below
0.686008   min_itemgetter
0.336031   min_loop

Correction: I forgot to apply list in the cases where map is an iterator, thus creating the iterator but not doing any real work... Thanks to gnibbler and Aशwini for pointing this out! 更正:map是迭代器的情况下,我忘记应用list ,从而创建了迭代器,但没有做任何实际工作...感谢gnibblerAशwini指出了这一点! With list(map(...)) , the execution times are pretty much the same as in Python 2.x, ie the plain old loop is still the fastest. 使用list(map(...)) ,执行时间与Python 2.x差不多,即普通的旧循环仍然是最快的。


Update 2: Interestingly, the "map-min-zip" solution is faster only for relatively short lists -- 'short' as in about 10,000 items. 更新2:有趣的是,“ map-min-zip”解决方案仅对于相对短的列表(“短”)(约10,000个项目)更快。 For longer lists, about 100,000 and more, the "itemgetter" solution becomes faster. 对于更长的列表(约100,000或更多),“ itemmetter”解决方案变得更快。 And the plain for-loop is always the fastest... 普通的for循环总是最快的...

You can use min here: 您可以在此处使用min

>>> from operator import itemgetter
>>> lst = [[0, 0], [1, 0], [0, 1], [-1, 0], [0, -1], [1, -1], [2, 0], [1, 1], [0, 2]]
>>> x = min(lst, key=itemgetter(0))[0]
>>> y = min(lst, key=itemgetter(1))[1]
>>> x, y
(-1, -1)

Takes around 1 second for 9000000 items on my system(i5 4670): 在我的系统上(i5 4670)需要9秒钟的时间约1秒:

In [3]: lst = lst*10**6

In [4]: %timeit (min(lst, key=itemgetter(0))[0], min(lst, key=itemgetter(1))[1])
1 loops, best of 3: 1.01 s per loop

A normal single loop version took around 341 ms: 普通的单循环版本大约需要341毫秒:

def find_min(seq):
    min_x = float('inf')
    min_y = float('inf')
    for x, y in seq:
        if x < min_x : min_x = x
        if y < min_y : min_y = y
    return min_x, min_y

Timing comparison: 时序比较:

len(lst)
Out[42]: 9000000

%timeit find_min(lst)
1 loops, best of 3: 341 ms per loop

%timeit map(min, zip(*lst))
1 loops, best of 3: 1.21 s per loop

%timeit map(min, izip(*lst))
1 loops, best of 3: 1.14 s per loop

%timeit (min(lst, key=itemgetter(0))[0], min(lst, key=itemgetter(1))[1])
1 loops, best of 3: 1.04 s per loop
minima = data[0]
for pair in data[1:]:
    minima = map(min, zip(pair, minima))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM