Как я могу получить минимальный элемент более эффективно?

#python #filter #min

#python #Фильтр #минимум

Вопрос:

У меня есть список, состоящий из элементов кортежа, подобных (id, cost, clicks, views) приведенному ниже:

 statistic_data_list = [(12324, 9, 6, 9), (12325, 11, 5, 3), (12326, 10, 7, 2)] 
  

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

  • 1 если не весь cost элемент равен 0, получите идентификатор элемента, который cost является наименьшим.
  • 2 когда все cost элементы равно 0, то, если не все clicks элементы равно 0, получаем идентификатор элемента, который clicks является наименьшим.
  • 3 когда все clicks элементы равно 0, то, если не все views элементы равно 0, получаем идентификатор элемента, который views является наименьшим.
 # (1)
#  input:  
[(12324, 9, 6, 9), (12325, 11, 5, 3), (12326, 10, 7, 2)]
#  expected result: 
12324 # (whose cost is lowest) 

# (2)
#  input:  
[(12324, 0, 6, 9), (12325, 0, 5, 3), (12326, 0, 7, 2)]
#  expected result:
12325 #  (whose clicks is lowest when all cost is 0)

# (3)
#  input:  
[(12324, 0, 0, 9), (12325, 0, 0, 3), (12326, 0, 0, 2)]
#  expected result: 
12326  #  (whose views is lowest when all cost is 0 also clicks)

  

Как я могу более эффективно получить идентификатор указанного элемента?

 # My attemp so far

cost_clicks_views_list = [(12324, 9, 6, 9), (12325, 11, 5, 3), (12326, 10, 7, 2)]

len_cost_not_0 = len(list(filter(lambda item: item[1], cost_clicks_views_list)))
len_clicks_not_0 = len(list(filter(lambda item: item[2], cost_clicks_views_list)))
len_views_not_0 = len(list(filter(lambda item: item[3], cost_clicks_views_list)))


if len_cost_not_0:
    min_cost_id_list = [ item[0] for item in cost_clicks_views_list if item[1]==min([i[1] for i in cost_clicks_views_list]) ]
    print(min_cost_id_list) # [(12324]

else:
    if len_clicks_not_0:
        min_clicks_id_list = [item[0] for item in cost_clicks_views_list if item[2] == min([i[2] for i in cost_clicks_views_list])]
        print(min_clicks_id_list) # [(12325]

    else:
        if len_views_not_0:
            min_views_id_list = [item[0] for item in cost_clicks_views_list if item[3] == min([i[3] for i in cost_clicks_views_list])]
            print(min_views_id_list)  # [12326]
  

Любые комментарии приветствуются. большое спасибо.

Комментарии:

1. (a) Ваши шансы получить отличный ответ возрастут, если ваши выборочные данные будут охватывать все упомянутые сценарии, и если вы также укажете ожидаемый результат для выборочных данных. В настоящее время я не думаю, что ваши примерные данные охватывают все упомянутые сценарии (b) Ваша текущая попытка делает несколько проходов по списку (я могу насчитать по крайней мере четыре прохода. Каждая len(filter()) операция занимает один проход). Я предполагаю, что вы должны быть в состоянии решить это за один проход.

2. В вашем примере данных показаны дробные значения для кликов

3. @fountainhead спасибо за ваш ответ, я исправил свою ошибку с дробными значениями для кликов.

Ответ №1:

Вы можете использовать понимание списка для их проверки. Когда хотя бы один cost из всех элементов не равен нулю, чтобы получить элемент, id у cost которого наименьший, попробуйте это :

 sdl = [(12324, 10, 0.6, 9), (12325, 11, 0.5, 3), (12326, 10, 0.7, 2)]
a = [j[0] for j in sdl if j[1]==min([k[1] for k in sdl if all([True if i[1] != 0 else False for i in sdl])])]
  

ВЫВОД :

 a = [12324, 12326]
  

Здесь все три элемента имеют ненулевое значение, cost а наименьшая стоимость 10 соответствует двум идентификаторам 12324 и 12326 .