Я не могу найти логическую ошибку в этом коде пузырьковой сортировки
-
05-09-2019 - |
Вопрос
Я пытаюсь выполнить простой код пузырьковой сортировки, чтобы ознакомиться с использованием манипуляций со списком / строкой и метода, но по какой-то причине, когда я пытаюсь выполнить итерацию по каждому значению в списке, чтобы удалить пробелы и значения, не являющиеся целыми числами, некоторые из них пропускаются.Я даже не добрался до части сортировки пузырьков..
#test data: 45,5j, f,e,s , , , 45,q,
if __name__ == "__main__":
getList = input("Enter numbers separated by commas:\n").strip()
listOfBubbles = getList.split(',')
print (listOfBubbles)
i = 0
for k in listOfBubbles:
listOfBubbles[i] = k.strip()
print ("i = {0} -- Checking '{1}'".format(i,listOfBubbles[i]))
if listOfBubbles[i] == '' or listOfBubbles[i] == ' ':
del listOfBubbles[i]
i -= 1
else:
try:
listOfBubbles[i] = int(listOfBubbles[i])
except ValueError as ex:
#print ("{0}\nCan only use real numbers, deleting '{1}'".format(ex, listOfBubbles[i]))
print ("deleting '{0}', i -= 1".format(listOfBubbles[i]))
del listOfBubbles[i]
i -= 1
else:
print ("{0} is okay!".format(listOfBubbles[i]))
i += 1
print(repr(listOfBubbles))
Выходной сигнал:
Enter numbers separated by commas:
45,5j, f,e,s , , , 45,q,
['45', '5j', ' f', 'e', 's ', ' ', ' ', ' 45', 'q', '']
i = 0 -- Checking '45'
45 is okay!
i = 1 -- Checking '5j'
deleting '5j', i -= 1
i = 1 -- Checking 'e'
deleting 'e', i -= 1
i = 1 -- Checking ''
i = 1 -- Checking '45'
45 is okay!
i = 2 -- Checking 'q'
deleting 'q', i -= 1
[45, 45, ' ', ' 45', 'q', '']
Решение
Как насчет более питонического способа?
#input
listOfBubbles = ['45', '5j', ' f', 'e', 's ', ' ', ' ', ' 45', 'q', '']
#Copy input, strip leading / trailing spaces. Remove empty items
stripped = [x.strip() for x in listOfBubbles if x.strip()]
# list(filtered) is ['45', '5j', 'f', 'e', 's', '45', 'q']
out = []
for val in filtered:
try:
out.append(int(val))
except:
# don't do anything here, but need pass because python expects at least one line
pass
# out is [45, 45]
Наконец, чтобы перейти к вашему правильному ответу
out.sort()
Обновить Для уточнения передайте
>>> for i in range(0,5):
pass
print i
0
1
2
3
4
Другие советы
Никогда не изменяйте сам список, на котором вы зацикливаетесь - внутри цикла for k in listOfBubbles:
, вы удаляете некоторые элементы из этого самого списка, и это нарушает внутреннюю логику цикла.Существует много альтернативных подходов, но самое простое решение - это зацикливание на Копировать из списка, который вы хотите изменить: for k in list(listOfBubbles):
.Могут возникнуть и другие проблемы, но это первая из них.
Неважно, исправил это.Я меняю цикл с a на for ..на какое-то время..
if __name__ == "__main__":
getList = input("Enter numbers separated by commas:\n").strip()
listOfBubbles = getList.split(',')
print (listOfBubbles)
i = 0
while i < len(listOfBubbles):
listOfBubbles[i] = listOfBubbles[i].strip()
print ("i = {0} -- Checking '{1}'".format(i,listOfBubbles[i]))
if listOfBubbles[i] == '' or listOfBubbles[i] == ' ':
del listOfBubbles[i]
i -= 1
else:
try:
listOfBubbles[i] = int(listOfBubbles[i])
except ValueError as ex:
#print ("{0}\nCan only use real numbers, deleting '{1}'".format(ex, listOfBubbles[i]))
print ("deleting '{0}', i -= 1".format(listOfBubbles[i]))
del listOfBubbles[i]
i -= 1
else:
print ("{0} is okay!".format(listOfBubbles[i]))
i += 1
print(repr(listOfBubbles))
Вы не можете использовать итератор для удаления из списка, потому что длина изменяется.
Вместо этого вы должны использовать индекс в цикле for (или цикле while).
Как только вы удалили элемент, вам нужно еще раз пройтись по списку.
псевдо-код:
again: for i = 0 to list.count - 1 { if condition then delete list[i] goto again; }
Если вы собираетесь удалить из списка во время итерации по нему, пройдите по списку в обратном порядке:
for( i = myList.length - 1; i >= 0; i-- ) {
// do something
if( some_condition ) {
myList.deleteItem( i );
}
}
Таким образом, вы не пропустите ни одного элемента списка, поскольку сокращение списка не повлияет ни на какие будущие итерации.Конечно, приведенный выше фрагмент предполагает, что метод DeleteItem поддерживается в классе list / array и выполняет соответствующие действия.