Проблема с обращением списка с использованием list.pop () - PullRequest
3 голосов
/ 19 ноября 2010

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

Сценарий, который я написал, выглядит следующим образом:

someStr = raw_input("Enter some string here:")
strList = []
for c in someStr:
    strList.append(c)

print strList

reverseCharList = []
for someChar in strList:
    reverseCharList.append(strList.pop())

print reverseCharList

Когда я ввожу строку abcd, возвращается результат [d, c].

Я знаюЯ изменяю список, который перебираю, но может кто-нибудь объяснить, почему символы 'a' и 'b' здесь не отображаются?

Спасибо

Ответы [ 4 ]

5 голосов
/ 19 ноября 2010
for someChar in strList:
    reverseCharList.append(strList.pop())

По сути то же самое, что и:

i = 0
while i < len(strList):
    reverseCharList.append(strList.pop())
    i += 1

Первая итерация i равна 0, len (strList) равен 4, и вы нажимаете + добавляете 'd'.

Второйитерация i равна 1, len (strList) равен 3, и вы щелкаете + добавляете 'c'.

Третья итерация i равна 2, len (strList) равно 2, поэтому условие цикла не выполняется, и все готово.

(Это действительно делается с помощью итератора в списке, а не локальной переменной 'i'. Я показал это таким образом для ясности.)

Если вы хотите манипулироватьпоследовательность, которую вы перебираете, обычно лучше использовать цикл while.например:

while strList:
    reverseCharList.append(strList.pop())
4 голосов
/ 19 ноября 2010

Как насчет простого обращения строки.

>>> x = 'abcd'
>>> x[::-1]
'dcba'
>>> 

По вашему коду:

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

>>> strList = [1, 2, 3, 4, 5]
>>> reverseCharList = []
>>> for someChar in strList:
...     print strList
...     reverseCharList.append(strList.pop())
...     print strList
... 
[1, 2, 3, 4, 5]   <-- Iteration 1
[1, 2, 3, 4]
[1, 2, 3, 4]      <-- Iteration 2
[1, 2, 3]
[1, 2, 3]         <-- Iteration 3
[1, 2]

См. Следующее. Так как вы используете итератор (для .. в ..). Вы можете видеть детали итератора напрямую и то, как мутирование списка портится с итератором.

>>> strList = [1, 2, 3, 4, 5]
>>> k = strList.__iter__()
>>> k.next()
1
>>> k.__length_hint__()   <--- Still 4 to go
4
>>> strList.pop()         <---- You pop an element
5
>>> k.__length_hint__()   <----- Now only 3 to go
3
>>> 
>>> k.next()
2
>>> k.__length_hint__()
2
1 голос
/ 19 ноября 2010

Простая рекурсивная версия:

def reverse(the_list):
    if not the_list:
        return []
    return [the_list.pop()] + reverse(the_list)

Конечно, [].reverse() быстрее.

1 голос
/ 19 ноября 2010

При сокращении вы сокращаете список.

reverseCharList = []
while strList:
    reverseCharList.append(strList.pop())
...