Переставить min и max число в списке

Условие: На вход программе подается строка текста, содержащая различные натуральные числа. Из данной строки формируется список чисел. Напишите программу, которая меняет местами минимальный и максимальный элемент этого списка. Например. Sample Input: 3 4 5 2 1 Sample Output: 3 4 1 2 5 и так далее. Для списка из одного элемента возвращается сам элемент. Ссылка на условие.

Я делал переменные для максимального и минимального значения, для их индексов. Потом удалил максимальное и минимальное значения. Потом на их место (по индексу) вставлял: макс. значение на место минимального и наоборот. Сразу не прошел тест где была одна цифра. Поскольку такой случай единичный, сделал для len(a) == 1 вывод print(*a), остальное же затолкал в else. Код получился такой:

a = list(map(int, input().split()))           

maxi = max(a)
mini = min(a)
pos_max = a.index(max(a))
pos_min = a.index(min(a))

if len(a) == 1:
    print(*a)
else:
    a.remove(maxi)
    a.remove(mini)
    a.insert(pos_max, mini)
    a.insert(pos_min, maxi)
    print(*a)

Ввод и вывод для теста: По состоянию на сейчас у меня: Failed test #6 of 8. Wrong answer Этот тест я даже не могу посмотреть, т.к. на степике всего 4 теста для этой задачи. Подставлял разные числа, в том числе отрицательные, трех- и более значные, нуль - всё работает. Подскажите, что не так? Вопросы в логике? Синтаксисе? Возможно, есть какие-то значения, где это не работает?


Ответы (3 шт):

Автор решения: Xander

Ну вот, например, последовательность на которой ваш код сломается: 2 1 2 3 2

В комментариях уже написали, почему такое происходит. Вы, конечно, можете учесть это всё, и для отдельных случаев из позиции вычитать единицу.

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

a = list(map(int, input().split()))           

maxi = max(a)
mini = min(a)
pos_max = a.index(max(a))
pos_min = a.index(min(a))

a[pos_min] = maxi
a[pos_max] = mini

print(*a)

Этот способ не только проще и надёжнее, но и вычислительно более экономный. При удалении-вставке каждый раз перестраивается часть списка, идущая после изменяемого элемента - и на больших списках это может быть затратно. А в моём способе меняется только пара нужных элементов, а остальная часть списка не меняется.

→ Ссылка
Автор решения: Stanislav

Первый вариант,от Xander, ИМХО, идеальный. Но можно и срезами делать. Полезно, если нужны более сложные замены. В большинстве случаев работает. Попробуйте:

a = list(map(int, input().split()))           

maxi = max(a)
mini = min(a)
pos_max = a.index(max(a))
pos_min = a.index(min(a))

if len(a) == 1:
    print(*a)
else:
    new_a = a[:pos_max] + [mini] + a[pos_max + 1:]
    new_a = new_a[:pos_min] + [maxi] + new_a[pos_min + 1:]
print(*new_a)
→ Ссылка
Автор решения: CrazyElf

Так, для общей эрудиции, чуть другое решение, использующее enumerate, ключ сортировки для min и max и упаковку-распаковку переменных:

a = list(map(int, input().split()))
a_i = list(enumerate(a))
pos_min, val_min = min(a_i, key=lambda x: x[1])
pos_max, val_max = max(a_i, key=lambda x: x[1])
a[pos_min], a[pos_max] = val_max, val_min
print(*a)
→ Ссылка