简体   繁体   中英

Algorithm (Python): find the smallest number greater than k

I have a question from algorithm point of view. I have a list of numbers (floats)

1.22,3.2, 4.9,12.3.....and so on

And I want to find the smallest number greater than (lets say) 4.. So the answer is 4.9 But besides the obvious solution.. (iterating thru list and keeping a track of smallest number greater than k) what is the "pythonic way" to do this. Thanks

min(x for x in my_list if x > 4)

Binary search would be a standard way to deal with this, but only if the list is sorted, as previous answer pointed out.

See Python binary search-like function to find first number in sorted list greater than a specific value

and In Python, how do you find the index of the first value greater than a threshold in a sorted list?

for discussion of a module that does this for you: http://docs.python.org/library/bisect.html

This is a perfect scenario for filter .

>>> L = [1.22, 3.2, 4.9, 12.3]
>>> k = 4
>>> a = min(filter(lambda x: x > k, L))
>>> print(a)
4.9

You could also use list comprehensions:

>>> L = [1.22, 3.2, 4.9, 12.3]
>>> k = 4
>>> a = min([element for element in L if element > k])
>>> print(a)
4.9

Although the list comprehension seems to be less straight-forward on the first view, it is the recommended way to do it. According to some Python developers, filter should not be used.

A generator expression is even better because it doesn't create the list in memory:

>>> L = [1.22, 3.2, 4.9, 12.3]
>>> k = 4
>>> a = min(element for element in L if element > k)
>>> print(a)
4.9

I've no idea about python, but from an algorithmic point of view maybe I can add something. In your example your list is monotonically increasing (sorted). If that is always true of your list, then a small optimization might be to stop iterating once you've reached a number larger than 4.

If your list always has few numbers lower than 4, this will be a great optimization, but if number of items before and after the target number is random, then this improvement isn't reliable.

In that case, you might want to search the list by partitioning it. Test if middle element is larger than 4. If it is larger, throw away upper half, otherwise throw away lower half. Do the same thing on the new half-length list. You need to deal with even and odd numbers and with the case when you have only 1 or 2 items left in the list-segment. For a large list, this should reduce the number of tests significantly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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