a mistake I keep having with for loops and return statements
<p>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. </p>

<p>I will give you an example of this happening with a code I just wrote:</p>

<pre><code>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
</code></pre>

<p>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:</p>

<pre><code>&gt;&gt;&gt;remove_exclamation('This is an example!')
'This is an example'
</code></pre>

<p>But instead I get this:</p>

<pre><code>&gt;&gt;&gt;remove_exclamation('This is an example!')
'This is an example!'
</code></pre>

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

<p>How can I keep avoiding this when I make for loops, nested for loops etc?</p>

<pre><code>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()
</code></pre>

<p>And <code>string</code> is still your input param, which I assume is of <code>type str</code>.  And immutable.</p>

<p>On top of which, if you were import/using the <code>string</code> <strong>module</strong>, you would be shadowing it</p>

<p>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.</p>

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

<p>Anyway, on to your question:</p>

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

print (remove_exclamation('This is an example!'))
</code></pre>

<p>output:<br>
<code>This is an example</code></p>

python python-3.x for-loop return return-value