минимум списка списков
У меня есть список списков, как так:
[[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]]
Я пытаюсь найти наименьшее значение для второго элемента в каждом списке (поэтому сравните 15-13-18 и т. д. не сравнивая 10564 и 15 ), но также разделить его на диапазоны, чтобы я мог сказать, самый низкий второй элемент[1] в каждом списке, только если элемент[0] превышает 10000 и т. д. Как мне это сделать? Я попробовал и могу сравнить только элементы в том же списке, что и сейчас, что не то, что я хочу. В случае, если я упоминаю, что я тогда вернусь [10787, 9] но если бы было другое значение более 10000 с 9, я бы тоже хотел вернуть его.
5 ответов
это зависит от того, что вы хотите для выхода. Во-первых, вам нужно будет отфильтровать свой список на основе "диапазонов" 1
gen = (x for x in lists if x[0] > 10000)
на if
условие может быть настолько сложным, насколько вы хотите (в пределах допустимого синтаксиса). например:
gen = (x for x in lists if 5000 < x[0] < 10000)
это прекрасно.
теперь, если вы хотите только второй элемент подсписка:
min(x[1] for x in gen)
конечно, вы можете встроить все это:
min(x[1] for x in lists if x[0] > 10000)
если вы хочу весь подсписок:
from operator import itemgetter
min(gen,key=itemgetter(1))
пример:
>>> 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]
к сожалению, это только даст вам первый подсписок, который соответствует критериям. Чтобы получить их все:
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)]
если вы точно знаете, что будет меньше, чем N
матчи, Вы могли бы сделать это немного более эффективно с heapq
и itertools.takewhile
. В общем случае, когда вы не знаете верхнего предела количества матчей, я думаю, что это решение лучше (Это O(N) по сравнению с сортировкой, которая является O (NlogN)).
1обратите внимание, что" выражение генератора " может быть повторено только один раз, прежде чем он будет исчерпан
вот очень простой подход, который просто находит минимальное значение, а затем строит список на основе этого значения.
>>> 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]
код правильно отображает несколько значений:
>>> 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]
Если вам требуется несколько min
s, тогда, возможно, вам лучше всего фильтровать применимые элементы и сортировать их...
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]]
тогда вы можете взять vals[0]
получить первый, vals[1]
чтобы получить второй, или использовать нарезку, такую как vals[:5]
...
>>> l=[[10564, 15], [10564, 13], [10589, 18], [10637, 39]]
>>> min(x[1] for x in l if x[0] > 10000)
13
>>>
обновление для вашего комментария (вы можете использовать лямбда для ключа в функции min, itemgetter немного быстрее в больших списках):
>>> min((x for x in l if x[0] > 10000), key=lambda k:k[1])
[10564, 13]
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)))