Создание максимального и минимального списка для скользящих подсписков

У меня есть список, содержащий подсписки:

[{'h': '20', 'l': '9'}, {'h': '30', 'l': '20'}, {'h': '25', 'l': '7'}, {'h': '18', 'l': '19'}, {'h': '22', 'l': '3'}]

Я хочу работать слева направо, находя максимум для «h» и минимум для «l» в уменьшающемся количестве оставшихся подсписков, включая текущий подсписок, на который ссылаются. Результат должен быть следующим.

[{'h': '30', 'l': '3'}, {'h': '30', 'l': '3'}, {'h': '25', 'l': '3'}, {'h': '22', 'l': '3'}, {'h': '22', 'l': '3'}]

Найти максимум и минимум всего списка достаточно просто, но я не могу найти лучший способ отбросить предыдущие подсписки и использовать только оставшиеся подсписки при создании нового списка.


person michael    schedule 27.01.2021    source источник


Ответы (3)


Этот код решает ваш вопрос:

inp = [{'h': '20', 'l': '9'}, {'h': '30', 'l': '20'}, {'h': '25', 'l': '7'}, {'h': '18', 'l': '19'}, {'h': '22', 'l': '3'}]
l1 = inp[::-1]
l2 = []

max1 = int(l1[0]['h'])
min1 = int(l1[0]['l'])
for item in l1:
  max1 = int(item['h']) if int(item['h'])>max1 else max1
  min1 = int(item['l']) if int(item['l'])<min1 else min1
  l2.append({'h':str(max1),'l':str(min1)})

l2 = l2[::-1]
print(l2)

Выход

[{'h': '30', 'l': '3'}, {'h': '30', 'l': '3'}, {'h': '25', 'l': '3'}, {'h': '22', 'l': '3'}, {'h': '22', 'l': '3'}]

Больше информации

Сначала я перевернул входной список и назвал его l1, затем перебрал l1, удерживая текущий max1 для h и min1 для l. Я добавлял max1 и min1 к l2 в каждой итерации. и, наконец, я перевернул список l2.

person Mahrad Hanaforoosh    schedule 27.01.2021

Вы можете использовать pandas для небольшой помощи. Сначала вы должны указать свои числа как целые числа, поскольку в настоящее время они являются строками.

l = [{'h': '20', 'l': '9'}, {'h': '30', 'l': '20'}, {'h': '25', 'l': '7'}, {'h': '18', 'l': '19'}, {'h': '22', 'l': '3'}]
l = [{k: int(v) for k, v in x.items()} for x in l]

Затем вы можете преобразовать их в фрейм данных и использовать cummax и cummin. Вам придется изменить порядок, чтобы получить его так, как вы описываете, а затем изменить этот вывод:

df = pd.DataFrame(l).iloc[::-1]
df['h'] = df['h'].cummax()
df['l'] = df['l'].cummin()
df = df.iloc[::-1]

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

df.to_dict('records')

[{'h': 30, 'l': 3},
 {'h': 30, 'l': 3},
 {'h': 25, 'l': 3},
 {'h': 22, 'l': 3},
 {'h': 22, 'l': 3}]
person busybear    schedule 27.01.2021

Вы можете решить эту задачу за O(n).

Представьте, что вы хотите решить эту проблему только для максимального значения (решение ее для минимального значения такое же), вам просто нужно выполнить итерацию от конца списка к началу, сохраняя при этом максимальные значения с их индексами, например, этот список будет следующим: [(22,4), (25,2), (30,1)].

Затем, когда вы захотите ответить, у вас будет цикл, начинающийся от 0 до 4, и пока ваш счетчик меньше или равен 1, ваш ответ будет 30. После этого, пока ваш счетчик меньше или равен 2, ваш ответ будет 25, и после этого, пока ваш счетчик меньше или равен 4, ваш ответ для максимального значения будет 22.

Та же теория применима для нахождения минимального значения.

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

data = [{'h': '20', 'l': '9'}, {'h': '30', 'l': '20'}, {'h': '25', 'l': '7'}, {'h': '18', 'l': '19'}, {'h': '22', 'l': '3'}]

mx_list = []
mx = 0          # Suppose numbers are Natural
mn_list = []    
mn = 1000000    # Suppose it is bigger than all of our numbers

for i, d in enumerate(reversed(data)):
    index = len(data) - i - 1
    print(int(d['h']))
    if int(d['h']) > mx:
         mx_list.append((int(d['h']), index))
         mx = int(d['h'])

for i, d in enumerate(reversed(data)):
    index = len(data) - i - 1
    print(int(d['l']))
    if int(d['l']) < mn:
         mn_list.append((int(d['l']), index))
         mn = int(d['l'])

answer_list = []

for i in range(len(data)):
    if i <= mx_list[len(mx_list)-1][1]:
        cur_mx = mx_list[len(mx_list)-1][0]
    else:
        mx_list.pop()
        cur_mx = mx_list[len(mx_list)-1][0]

    if i <= mn_list[len(mn_list)-1][1]:
        cur_mn = mn_list[len(mn_list)-1][0]
    else:
        mn_list.pop()
        cur_mn = mn_list[len(mn_list)-1][0]
    
    answer_list.append({'h': cur_mx, 'l': cur_mn})

print(answer_list)
person MohammadMahdi Eilbeigi    schedule 27.01.2021