Home > Blockchain >  Why is Python not removing this character?
Why is Python not removing this character?

Time:11-02

This is my first experience with Python. I'm following an exercise out of the Head First Python book. I'm trying to convert one string into another string. (Changing "Don't panic!" into "on tap".) First, I convert the string into a list. Then, I use an if statement in a for loop to filter out the letters that I don't need.

I'm getting some very strange behavior, though! Here's my code:

phrase = "Don't panic!"
plist = list(phrase)
print(phrase)
print(plist)

for character in plist:
    if character not in ['o', 'n', 't', 'a', 'p', ' ']:
        plist.remove(character)
        print("removing ", character)
new_phrase = ''.join(plist)
print(plist)
print(new_phrase)

And here's my output:

Don't panic!
['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']
removing  D
removing  '
removing  i
removing  !
['o', 'n', 't', ' ', 'p', 'a', 'n', 'c']
ont panc

Why is the letter "c" still there? It's not in the array that I used in the if statement, and the rest of the characters get filtered out. But not the "c". Why?

CodePudding user response:

To show what I was suggesting in my comment, here's your code, modified:

phrase = "Don't panic!"
plist = list(phrase)
print(phrase)
print(plist)
removable = []
for character in plist:
    if character not in ['o', 'n', 't', 'a', 'p', ' ']:
        removable.append(character)
for character in removable:
        plist.remove(character)
        print("removing ", character)
new_phrase = ''.join(plist)
print(plist)
print(new_phrase)

(Actually, you would be better off making removable a set, to eliminate duplicate entries, but I leave that as an exercise.)

CodePudding user response:

why this behaviour ?

first you are deleting a list whose generate object is looping in the for loop. making the list dynmic. so whenever you delete a index from a list lets say D , 0th index, then [ 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] this becomes your list.

now since generator object when deleting D was at index 0, then next(object) would point to 1st index of remaining list. so that would be 'n value. Note it didn't go through the o at newly updated index. this same happens when it passes through the c.

to verify this here is a result code

plist = list(phrase)
print(phrase)
print(plist)

for index, character in enumerate(plist):
    print(plist, character, index)
    if character not in ['o', 'n', 't', 'a', 'p', ' ']:
        plist.remove(character)
        # print("removing ", character)
new_phrase = ''.join(plist)
print(plist)
print(new_phrase)

result

Don't panic!
['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']
['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] D 0
['o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] n 1
['o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] ' 2
['o', 'n', 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']   3
['o', 'n', 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] p 4
['o', 'n', 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] a 5
['o', 'n', 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] n 6
['o', 'n', 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] i 7
['o', 'n', 't', ' ', 'p', 'a', 'n', 'c', '!'] ! 8
['o', 'n', 't', ' ', 'p', 'a', 'n', 'c']
ont panc

you can see how list is behaving when a value is deleted

  • Related