как получить элементы в списке кортежей на основе значения в кортеже - PullRequest
0 голосов
/ 10 сентября 2018

Я получаю комбинированный список данных и сортирую его, используя функцию zip

comb_list = sorted(zip(score_list, move_list), key = lambda pair: pair[0], reverse = True)

выход - что-то вроде этого

a = [(3, (5, 4, False)), (3, (6, 4, False)), (2, (5, 1, False)), 
(1, (6, 2, False)), (-1, (6, 2, False))] 

Я хочу отсортировать по первому элементу в кортеже (в списке), найти максимальное значение и вывести второй элемент в кортеже. Здесь максимальное значение равно 3, а на выходе будет

[(5, 4, False), (6, 4, False)]

или, если у меня есть

a = [(3, (5, 4, False)), (2, (5, 1, False)), (1, (6, 2, False)), (-1, (6, 2, False))] 

и вывод будет

[(5, 4, False)]

Ответы [ 3 ]

0 голосов
/ 10 сентября 2018

Очень простой и питонический способ ее решения

>>> max_value = max(a, key=lambda x:x[0])[0]
>>> max_value
3
>>> [x[1] for x in a if x[0]==max_value]
[(5, 4, False), (6, 4, False)]

Вы можете использовать max встроенный метод с ключом:

 >>> a = [(3, (5, 4, False)), (3, (6, 4, False)), (2, (5, 1, False)),
... (1, (6, 2, False)), (-1, (6, 2, False))]
>>> max([(x,list(y)) for x,y in itertools.groupby(sorted(a, key=lambda x:x[0]), key=lambda x:x[0])], key=lambda x:x[0])
(3, [(3, (5, 4, False)), (3, (6, 4, False))])
0 голосов
/ 10 сентября 2018

Есть более эффективные способы сделать это, чем сортировать весь список и затем фильтровать, но, поскольку вы уже отсортировали весь список по ключу и, вероятно, поняли, как это работает, давайте начнем с этого:

a = [(3, (5, 4, False)), (3, (6, 4, False)), (2, (5, 1, False)), (1, (6, 2, False)), (-1, (6, 2, False))] 

Итак, теперь вы хотите отфильтровать его только по тем, чей ключ совпадает с верхним:

b = [(key, value) for key, value in a if key == a[0][0]]

… за исключением того, что вы просто хотите value, а не пару (key, value), что просто:

b = [value for key, value in a if key == a[0][0]]

Теперь, почему это неэффективно? Ну, если вы уже отсортировали список, вам не нужно проверять каждое значение ; Вы можете выйти из цикла, как только найдете тот, который не соответствует (например, с itertools.takewhile). Но, проще говоря, вам не нужно сортировать в первую очередь; просто получите max, а затем используйте его для фильтрации:

comb_list = list(zip(score_list, move_list))
comb_max = max(comb_list, key=lambda pair: pair[0])
b = [value for key, value in comb_list if key==comb_max[0]]

Или, что еще лучше, вам даже не нужно составлять промежуточный список, потому что max не нуждается в zip. Что также делает вещи намного проще для понимания:

max_score = max(score_list)
b = [move for score, move in zip(score_list, move_list) if score == max_score]
0 голосов
/ 10 сентября 2018

Использование списка понимания:

a = [(5, (5, 4, False)), (3, (6, 4, False)), (2, (5, 1, False)),(1, (6, 2, False)), (-1, (6, 2, False))]
filtered = [p[1] for p in a if p[0] >= max([x[0] for x in a])]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...