MountainSlayer
MountainSlayer

Reputation: 321

a mistake I keep having with for loops and return statements

I have been noticing a problem I am having whenever I try to make a function that takes changes a string or a list then returns it.

I will give you an example of this happening with a code I just wrote:

def remove_exclamation(string):
string.split(' ')
for i in string:
    i.split()
    for char in i:
        if char == '!':
            del char
            ''.join(i)
            ' '.join(string)
return string

For instance, I create this code to take a string as its parameter, remove any exclamation in it, the return it changed. The input and output should look like this:

>>>remove_exclamation('This is an example!')
'This is an example'

But instead I get this:

>>>remove_exclamation('This is an example!')
'This is an example!'

The function is not removing the exclamation in the output, and is not doing what I intended for it to day.

How can I keep avoiding this when I make for loops, nested for loops etc?

Upvotes: 3

Views: 100

Answers (4)

JL Peyret
JL Peyret

Reputation: 12164

def remove_exclamation(string):

    #you think you are splitting string into tokens
    #but you are not assigning the split anywhere...
    string.split(' ')

    #and here you are cycling through individual _chars_ in string which was not affected by the split above ;-)
    for i in string:
        #and now you are splitting a 1-char string and again not assigning it.
        i.split()

And string is still your input param, which I assume is of type str. And immutable.

On top of which, if you were import/using the string module, you would be shadowing it

A big part of your confusion is knowing when the methods mutate the objects and when they return a new object. In the case of strings, they never mutate, you need to assign the results to a new variable.

On a list however, and the join() somewhere makes me think you want to use a list, then methods generally change the object in place.

Anyway, on to your question:

def remove_exclamation(inputstring, to_remove="!"):
    return "".join([c for c in inputstring if c != to_remove])

print (remove_exclamation('This is an example!'))

output:
This is an example

Upvotes: 0

Chris
Chris

Reputation: 22953

Strings are immutable in Python. And you cannot change them. You can however, re-assign there values.

That is where your problem lies. You never reassign the value of your strings, when you call .split() on them.

But there are also others errors in your program such as:

  • Your indention
  • The fact that your just returning the string thats passed into the function
  • Your use of the del statement
  • etc.

Instead, create a new string by iterating through the old one and filtering out the character(s) you do not want, via list comprehension and ''.join().

def remove_exclamation(string):
    return ''.join([char for char in string if char != '!'])

But as @Moses has already said in the comments, why not just use str.replace()?:

string = string.replace('!', '')

Upvotes: 0

CodeLikeBeaker
CodeLikeBeaker

Reputation: 21312

Without clearly knowing the intentions of your function and what you are attempting to do. I have an alternative to the answer that zvone gave.

This option is to remove any characters that you have not defined in an allowed characters list:

characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "

test_string = "This is an example!"

test_string = ''.join(list(filter(lambda x: x in characters, test_string)))

print(test_string)

This outputs:

This is an example

Note, this is the Python 3 version.

Python 2, you do not need the ''.join(list())

Doing it this way would allow you to define any character that you do not want present in your string, and it will remove them.

You can even do the reverse:

ignore_characters= "!"

test_string = "This is an example!"

test_string = ''.join(list(filter(lambda x: x not in ignore_characters, test_string)))

print(test_string)

Upvotes: 1

zvone
zvone

Reputation: 19352

You write your code and formulate your question as if it was possible to modify strings in Python. It is not possible.

Strings are immutable. All functions which operate on strings return new strings. They do not modify existing strings.

This returns a list of strings, but you are not using the result:

string.split(' ')

This also:

i.split()

This deletes the variable named char. It does not affect the char itself:

        del char

This creates a new string which you do not use:

        ''.join(i)

This also:

        ' '.join(string)

All in all, almost every line of the code is wrong.

You probably wanted to do this:

def remove_exclamation(string):
    words = string.split(' ')
    rtn_words = []
    for word in words:
        word_without_exclamation = ''.join(ch for ch in word if ch != '!')
        rtn_words.append(word_without_exclamation)
    return ' '.join(rtn_words)

But in the end, this does the same thing:

def remove_exclamation(string):
    return string.replace('!', '')

Upvotes: 4

Related Questions