Расширенное понимание списка
Список целых чисел вводится в программу 1 за один раз, например:
[1, 3, 1, 4, 4, 3, 1]
Задача:
Распечатайте список, который содержит точно такие же числа, что и данный список,
но переставить так, чтобы за каждыми 3 сразу следовали цифры 4. 3 не должны перемещать индексные места, но могут перемещаться все остальные числа.
Вывод примера должен выглядеть следующим образом:
[1, 3, 4, 1, 1, 3, 4]
Мой код до сих пор может выполнять только правила 1 и 2. Как мой код может быть изменен для удовлетворения этого?
newList=[]
n=0
numCount= int(input())
while True:
try:
n = int(input())
except:
break
if len(newList) !=(numCount):
if n == 3:
newList.append(3)
newList.append(4)
else:
newList.append(n)
print(newList)
3 ответа
Я предлагаю вам сначала получить все индексы 3 и 4 в списке ввода, а затем поменять местами каждый элемент, следующий за 3, с 4. Он дает следующий код, который довольно короткий и легко читаемый:
a = [1, 3, 1, 4, 4, 3, 1]
# Get the indexes of 3 and 4 in the list
indexesOf3 = [i for i,elem in enumerate(a) if elem == 3]
indexesOf4 = [i for i,elem in enumerate(a) if elem == 4]
# Swap each element following a 3 with a 4
for i3,i4 in zip(indexesOf3,indexesOf4):
a[i3+1], a[i4] = a[i4], a[i3+1]
print(a)
# [1, 3, 4, 1, 1, 3, 4]
Примечание: этот пример кода изменяет список ввода, но, очевидно, его можно легко обновить в функцию, возвращающую новый список и сохраняющую список ввода как есть.
Ваш вопрос не очень четко определен, и потерянный сценарий не учитывается. Этот код делает работу довольно просто, идея состоит в том, чтобы создать новый список.
-Найдите позицию 3 на входе
-Заменить 3, а затем 4 в новом списке
-Установите остальные элементы.
input_list = [1, 3, 1, 4, 4, 3, 1]
# Check the number of 3 and 4
n3 = input_list.count(3)
n4 = input_list.count(4)
if n3 > n4:
for i in range(n3-n4):
input_list.append(4)
elif n4 > n3:
for i in range(n4-n3):
input_list.append(3)
# Now let's look at the order. The 3 should not move and must be followed by a 4.
# Easy way, create a new list.
output_list = [None for i in range(len(input_list))]
# Then I'm using numpy to go faster but the idea is just to extract the ids are which the 3 are placed.
import numpy as np
# Place the 3 and the 4
for elt_3 in np.where(np.asarray(input_list) == 3)[0]:
output_list[elt_3] = 3
output_list[elt_3+1] = 4 # Must be sure that the input_list does not end by a 3 !!!
# Then we don't care of the position for the other numbers.
other_numbers = [x for x in input_list if x != 3 and x != 4]
for i, elt in enumerate(output_list):
if elt is None:
output_list[i] = other_numbers[0]
del other_numbers[0]
print (output_list)
В более компактной версии с одним контуром это дает:
input_list = [1, 3, 1, 4, 4, 3, 1]
position_3 = np.where(np.asarray(input_list) == 3)[0]
other_numbers = [x for x in input_list if x != 3 and x != 4] # Not 3 and not 4
output_list = [None for i in range(len(input_list))]
for i, elt in enumerate(output_list):
if elt == 4:
continue
elif i not in position_3:
output_list[i] = other_numbers[0]
del other_numbers[0]
else:
output_list[i] = 3
output_list[i+1] = 4
Вот функция, которая делает именно это:
def arrange_list(my_list):
# Copy the whole list
arranged_list=myList.copy()
# Find the all 4s
index_of_4s=[i for i, x in enumerate(arranged_list) if x == 4]
next_4=0
# Loop over the whole list
for i in range(len(arrangedList)):
if(arrangedList[i]==3): # We only care about 3s
# We swap the previously found 4 with a 1
arranged_list[index_of_4s[next_4]]=arranged_list[i+1]
arranged_list[i+1]=4
# We target the next 4
next_4=next_4+1
return arranged_list
Если мы проверим это на вашем примере, мы получим:
myList=[1, 3, 1, 4, 4, 3, 1]
arrange_list(myList)
#> [1, 3, 4, 1, 1, 3, 4]