Это базовое c упражнение по программированию, поэтому давайте подойдем к нему с большинством базовых c Python конструкций. Простой алгоритм будет отслеживать индекс, где обнаружен первый ноль, и менять ненулевые числа на ту позицию, которую мы затем продвигаем. Это будет переносить нули по списку до тех пор, пока все нули не будут сгруппированы в конце.
numbers = [1, 3, 0, 2, 6, 0, 7]
firstZero = -1 # track position of first zero
for index,number in enumerate(numbers): # go through numbers in list
if firstZero < 0:
if number == 0: # do nothing until a zero is found
firstZero = index # start tracking first zero position
elif number != 0:
numbers[firstZero] = number # swap non-zero numbers
numbers[index] = 0 # with zero position
firstZero += 1 # and advance first zero position
print(numbers)
# [1, 3, 2, 6, 7, 0, 0]
Отслеживая прогресс l oop, вы можете увидеть движение позиции firstZero относительно Индекс и перенос нулей по списку:
# firstZero index number numbers
# -1 0 1 [1, 3, 0, 2, 6, 0, 7] # do nothing
# Z ^
# -1 1 3 [1, 3, 0, 2, 6, 0, 7] # do nothing
# Z ...^
# 2 2 0 [1, 3, 0 2, 6, 0, 7] # record position of 1st zero
# ..........Z^
# 3 3 2 [1, 3, 2<->0, 6, 0, 7] # swap non-zero (2),
# ...Z^ # advance position of 1st zero
# 4 4 6 [1, 3, 2, 6<->0, 0, 7] # swap non-zero (6),
# ...Z^ # advance position of 1st zero
# 4 5 0 [1, 3, 2, 6, 0, 0, 7] # ignore subsequent zeroes
# Z ..^ # do nothing
# 5 6 0 [1, 3, 2, 6, 7<- 0,->0] # swap non-zero (7),
# ...Z ..^ # advance position of 1st zero
С другой стороны, если вам нужен мета-трюк, вы можете использовать стабильность сортировки Python и ее способность сортировать для вычисляемого ключа для группировки чисел между ненулевыми значениями и нулями:
numbers.sort(numbers,key=lambda n:not n)
Параметр ключа использует функцию для получения ключа для сортировки (в отличие от самих чисел). Эта функция здесь not n
, которая при применении к целому числу возвращает True, если она равна нулю, и False, если это не так. Это будет сопоставлять ключи сортировки с числами следующим образом:
False, False, True, False, False, True, False
[1, 3, 0, 2, 6, 0, 7]
Сортировка логических значений будет помещать ложные значения перед True, а стабильность сортировки Python будет сохранять относительный порядок элементов для идентичных значений ключей. :
False, False, False, False, False True, True
[1, 3, 2, 6, 7, 0, 0]
Рассчитанные значения ключей существуют только в процессе сортировки, в результате получается только список номеров, отсортированный соответствующим образом.
Хотя использование функции сортировки является хорошим трюком, с точки зрения сложности она будет выполняться за O (n log n) времени. Более специализированный алгоритм basi c способен выполнять ту же работу за один проход данных, которые будут выполняться за O (n) времени.
Другой способ сгруппировать нули в конце Список за O (n) время состоит в том, чтобы построить новый список, составив список ненулевых элементов со списком нулей соответствующей длины:
nonZero = [*filter(bool,numbers)]
numbers = nonZero + [0]*(len(numbers)-len(nonZero))
Затем список nonZero
строится с использованием понимание списка с распаковкой результата из итератора фильтра. Вторая часть представляет собой повторение списка с нулем для количества раз, необходимого для достижения исходной длины.