Как сравнить значения индекса в списке по умолчанию в python - PullRequest
3 голосов
/ 29 сентября 2019

У меня есть по умолчанию dict d в python, который содержит два списка, как показано ниже:

{
    'data1': [0.8409093126477928, 0.9609093126477928, 0.642217399079215, 0.577003839123445, 0.7024399719949195, 1.0739533732043967], 
    'data2':  [0.9662666242560285, 0.9235637581239243, 0.8947656867577896, 0.9266919525550584, 1.0220039913024457]
}

В будущем может быть много списков в по умолчанию dict, таких как data1, data2, data3, data4 и т. Д. Мне нужно сравнить значения индекса по умолчанию dict друг с другом.Таким образом, для вышеуказанного значения по умолчанию мне нужно проверить, что погода data1[0]->0.8409093126477928 меньше, чем data2[0]->0.9662666242560285 или нет, и то же самое относится и к другому индексу, и сохранить результат индекса списка победителей в отдельном списке, как показано ниже:

result = ['data1', 'data2', 'data1', 'data1', 'data1']

Если длина любого списка больше, чем у другого списка, нам просто нужно проверить, меньше ли последнее значение индекса, чем 1, или нет.Подобно data1[5] нельзя сравнивать с data2[5], поскольку нет значения data2[5], поэтому мы просто проверим, меньше ли data1[5] 1 или нет.Если его значение меньше 1, мы рассмотрим его и добавим в result, иначе проигнорируем его и не сохраним его в result.

Чтобы решить эту проблему, я думал, извлечь список из значения по умолчанию дляотдельный список и затем использование цикла for для сравнения значений индекса, но когда я сделал print(d[0]) для печати списка индексов 0th, он распечатал [].Почему печать ноль.Как я могу сравнить значения индекса, как указано выше.Пожалуйста помоги.Спасибо

Ответы [ 4 ]

1 голос
/ 29 сентября 2019
d = {
    'd0': [0.1, 1.1, 0.3],
    'd1': [0.4, 0.5, 1.4, 0.3, 1.6],
    'd2': [],
}

import itertools
import collections

# sort by length of lists, shortest first and longest last
d = sorted(d.items(), key=lambda k:len(k[1]))

# loop through all combinations possible
for (key1, list1), (key2, list2) in itertools.combinations(d, 2):
    result = []
    for v1, v2 in itertools.zip_longest(list1, list2): # shorter list is padded with None
        # no need to check if v2 is None because of sorting
        if v1 is None:
            result.append(key2 if v2 < 1 else None)
        else:
            result.append(key1 if v1 < v2 else key2)

    # DO stuff with result, keys, list, etc...
    print(f'{key1} vs {key2} = {result}')

Вывод

d2 vs d0 = ['d0', None, 'd0']
d2 vs d1 = ['d1', 'd1', None, 'd1', None]
d0 vs d1 = ['d0', 'd1', 'd0', 'd1', None]

Я отсортировал их по длине списка.Это гарантирует, что list1 всегда будет короче или будет иметь ту же длину, что и list2.

. Для различных длин оставшиеся индексы будут представлять собой смесь None и key2.

*.1013 * Однако, когда элементы равны, key2 добавляется к результату.Это может быть нежелательным поведением.
1 голос
/ 29 сентября 2019

Редактировать : как предложено @ggorlen, заменил пользовательский итератор на zip_longest

Я бы сделал это с помощью custom_iterator, как это,

  • zip longest yeild oneэлемент из каждого массива в каждой итерации.для более короткого массива он вернет 1, когда итерация пройдет ее длину
  • Цикл понимания списка через итератор и получит 1-й индекс элемента min item.index(min(item)), затем получит ключ, соответствующий минимальному значению keys[item.index(min(item))]
  • если выбранный список короче текущего индекса итератора, он либо пропускает, либо задает значение "NA"
from itertools import zip_longest

keys = list(d.keys())
lengths = list(map(len,d.values()))

result = [keys[item.index(min(item))] 
          for i, item in enumerate(zip_longest(*d.values(), fillvalue=1))
          if lengths[item.index(min(item))]>i]

result

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

result = [keys[item.index(min(item))] if lengths[item.index(min(item))]>i else "NA"
          for i, item in enumerate(zip_longest(*d.values(), fillvalue=1))]
1 голос
/ 29 сентября 2019

Мы можем использовать zip_longest из itertools и множество циклов для достижения результата:

from itertools import zip_longest

result = []
pairs = [[[z, y] for z in x] for y, x in data.items()]

for x in zip_longest(*pairs):
    x = [y for y in x if y]

    if len(x) > 1:
        result.append(min(x, key=lambda x: x[0])[1])
    elif x[0][0] < 1:
        result.append(x[0][1])

print(result) # => ['data1', 'data2', 'data1', 'data1', 'data1']

Сначала мы создаем пары каждого элемента в каждом значении dict и его ключе,Это облегчает получение ключей результата позже.Мы zip_longest и перебираем списки, отфильтровывая None s.Если у нас есть более одного элемента для сравнения, мы берем min и добавляем его к результату, иначе мы проверяем одинокий элемент и сохраняем его, если его значение меньше 1.

Более проверяемый пример:

data = {
    'foo':  [1, 0, 1, 0], 
    'bar':  [1, 1, 1, 1, 0],
    'baz':  [1, 1, 0, 0, 1, 1, 0],
    'quux': [0],
}

, который производит

['quux', 'foo', 'baz', 'foo', 'bar', 'baz']

По элементам, "quux" выигрывает раунд 0, "foo" выигрывает раунд 1, "baz" 2, "foo" раунд 3 благодаря ключупорядок (связанный с "baz"), "bar" для 4-го раунда. Для 5-го раунда "baz" - последний стоящий, но не ниже 1, поэтому ничего не берется.В 6 раунде "baz" остается последним, но с 0 <1 берется. </p>

0 голосов
/ 29 сентября 2019

Может ли это быть что-то вроде этого

def compare2List(a, b):
   '''
   Input name of 2 lists that you need to compare
   a = name of 1st list appearing in dict d
   b = name of 2nd list appearing in dict d
   '''
   data1 = d[a]
   data2 = d[b]
   result = list()
   i = 0
   while i < len(data1) OR i < len(data2):
      if i < len(data1) AND i < len(data2):
         if data1[i] < data2[i]:
            result.append("data1")
         else:
            result.append("data2")
      else:
         if i >= len(data1):
            if data1[0] < 1:
               result.append("data1")
         elif i >= len(data2):
            if data2[0] < 1:
               result.append("data2")

      i = i + 1

   return result
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...