minimum of list of lists

放肆的年华 提交于 2021-02-18 20:47:32

问题


I have a list of lists like so:

[[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66,
 17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]]

I am trying to find the lowest value for the second element in each list(so compare 15 to 13 to 18 etc not comparing 10564 and 15 ), but also to separate it into ranges, so I could say, lowest second element[1] in each list, only if element[0] is over 10000 etc. How might I do this? I tried it and can only compare elements in the same list as of yet, which is not what I want. In the case I mentions I would then be returning [10787, 9] but if there was another value over 10000 with 9 I would want to return that also.


回答1:


This depends on what you want for output. First, you'll need to filter your list based on the "ranges" 1

gen = (x for x in lists if x[0] > 10000)

The if condition can be as complicated as you want (within valid syntax). e.g.:

gen = (x for x in lists if 5000 < x[0] < 10000)

Is perfectly fine.


Now, If you want only the second element from the sublists:

min(x[1] for x in gen)

Of course, you could inline the whole thing:

min(x[1] for x in lists if x[0] > 10000)

If you want the entire sublist:

from operator import itemgetter
min(gen,key=itemgetter(1))

example:

>>> lists = [[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66,17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]]
>>> gen = (x for x in lists if x[0] > 10000)
>>> min(x[1] for x in gen)
9
>>> gen = (x for x in lists if x[0] > 10000)
>>> from operator import itemgetter
>>> min(gen,key=itemgetter(1))
[10787, 9]

Unfortunately, these only give you the first sublist which matches the criteria. To get all of them:

target = min(x[1] for x in lists if x[0] > 10000)
matches = [x for x in lists if (x[1] == target) and (x[0] > 10000)]

If you know for sure that there will be less than N matches, you could do this a little more efficiently with heapq and itertools.takewhile. In the general case where you don't know an upper limit on the number of matches, I think this solution is better (It's O(N) compared to sorting which is O(NlogN)).


1Note that the "generator expression" can only be iterated over once before it is exhausted




回答2:


>>> l=[[10564, 15], [10564, 13], [10589, 18], [10637, 39]]
>>> min(x[1] for x in l if x[0] > 10000)
13
>>>

update for your comment (you can use lambda for key in min function, itemgetter a little faster on large lists):

>>> min((x for x in l if x[0] > 10000), key=lambda k:k[1])
[10564, 13]



回答3:


Here's a very simply approach that just finds the minimum value and then builds the list based on that value.

>>> a = [[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66,
...  17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]]
>>> a_min = min(i[1] for i in a)
>>> [i[0] for i in a if i[1] == a_min and i[0] > 10000] + [a_min]
[10787, 9]

The code correctly displays multiple values:

>>> a += [[10391, 9]] #add another pair with a first value > 10000
>>> [i[0] for i in a if i[1] == a_min and i[0] > 10000] + [a_min]
[10787, 10391, 9]



回答4:


If you require multiple mins, then perhaps you're best of filtering applicable elements and sorting them...

vals = sorted((el for el in your_list if el[0] >= 10000), key=lambda L: L[1])
# [[10787, 9], [10812, 12], [10564, 13], [10762, 14], [10564, 15], [10737, 15], [10589, 18], [10662, 38], [10637, 39], [10837, 45], [10712, 50]]

Then you can take vals[0] to get the first, vals[1] to get the second, or use slicing such as vals[:5]...




回答5:


a=[[10564, 15], [10564, 13], [10589, 18], [10637, 39], [10662, 38], [10712, 50], [10737, 15], [10762, 14], [10787, 9], [10812, 12], [10837, 45], [3, 17], [7, 21], [46, 26], [48, 12], [49, 24], [64, 14], [66, 17], [976, 27], [981, 22], [982, 22], [983, 17], [985, 13], [517, 9], [521, 15], [525, 11], [526, 13], [528, 14], [698, 14], [788, 24], [792, 19]]

print min(map(lambda y: y[1] ,filter(lambda x: x[0]>10000,a)))


来源:https://stackoverflow.com/questions/16036913/minimum-of-list-of-lists

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!