Why won't the list delete function delete spaces?
<pre><code>string = "hello world i'm a new program"
words_length = []
length = 21
</code></pre>

<p>I'm using <code>re.split</code> to produce a list of words and spaces:</p>

<pre><code>words = re.split('\w', string)
</code></pre>

<p>so: </p>

<pre><code>words = ['hello', ' ', 'world', ' ', 'i', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']

for x in words:
    words_length.append(len(x))

    for x in range(len(words)):
        if words_length &lt; length:
        words_length += letters_length[x]
        line += words[x]    
        del words[x]
</code></pre>

<p>but at the end when I print the variables I get:</p>

<pre><code>line = "helloworldi'manew"
words = [' ', ' ', ' ', ' ', ' ', 'program']
</code></pre>

<p>But what I want is:</p>

<pre><code>line = "hello world i'm a new"
words = ['program']
</code></pre>

<p>How can I manage to do that?</p>

<p>You are <em>skipping indices</em> because you are deleting characters from your list.</p>

<p>Each time you delete a character, everything to the <em>right</em> of that character shifts up one step to the left, and their index goes down by one. But your <code>x</code> index still goes up by one so now you are referencing a later element in the list:</p>

<ol>
<li><p>first iteration of the for loop:</p>

<pre><code>x == 0
words == ['hello', ' ', 'world', ' ', 'i', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']
#        0        1    2        3    4    5    ...
words[x] == 'hello'

del words[x]
words == [' ', 'world', ' ', 'i', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']
#         0    1        2    3    4    5    ...
</code></pre></li>
<li><p>second iteration of your loop:</p>

<pre><code>x == 1
words == [' ', 'world', ' ', 'i', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']
#         0    1        2    3    4    5    ...
words[x] == 'world'

del words[x]
words == [' ', ' ', 'i', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']
#         0    1    2    3    4    5    ...
</code></pre></li>
<li><p>third iteration of your loop</p>

<pre><code>x == 2
words == [' ', ' ', 'i', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']
#         0    1    2    3    4    5    ...
words[x] == 'i'

del words[x]
words == [' ', ' ', "'", 'm', ' ', 'a', ' ', 'new', ' ', 'program']
#         0    1    2    3    4    5    ...
</code></pre></li>
</ol>

<p>Don't remove entries from your list until at least <em>after</em> looping; you don't need to have them removed during the loop:</p>

<pre><code>line = []
current_length = 0
for i, word in enumerate(words):
    current_length += len(word)
    if current_length &gt; length:
        i -= 1
        break
    line.append(word)
# here i is the index of the last element of words actually used
words = words[i + 1:]  # remove the elements that were used.
line = ''.join(line)
</code></pre>

<p>or you could remove words (from a reversed list for efficiency), but then use a <code>while</code> loop and test for the accumulated length instead:</p>

<pre><code>line = []
current_length = 0
reversed_words = words[::-1]
while reversed_words:
    l = len(reversed_words[-1])
    if current_length + l &gt; length:
        break
    line.append(reversed_words.pop())
    current_length += l
words = reversed_words[::-1]
line = ''.join(line)
</code></pre>

<p>However, if you are trying to apply line-length wrapping to a Python string, you could avoid re-inventing that wheel by using the <a href="https://docs.python.org/2/library/textwrap.html" rel="nofollow"><code>textwrap</code> module</a> instead. It can do line-wrapping within a maximum length for you with ease:</p>

<pre><code>wrapped = textwrap.fill(string, length)
</code></pre>

python list python-3.x for-loop