为什么列表删除功能不会删除空格?

时间:2016-09-14 11:53:20

标签: python list python-3.x for-loop

string = "hello world i'm a new program"
words_length = []
length = 21

我正在使用re.split来生成单词和空格列表:

words = re.split('\w', string)

所以:

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 < length:
        words_length += letters_length[x]
        line += words[x]    
        del words[x]

但是当我打印变量时,我得到了:

line = "helloworldi'manew"
words = [' ', ' ', ' ', ' ', ' ', 'program']

但我想要的是:

line = "hello world i'm a new"
words = ['program']

我怎样设法做到这一点?

1 个答案:

答案 0 :(得分:3)

您正在跳过索引,因为您要删除列表中的字符。

每次删除一个角色时,该角色的右侧的所有内容都会向左移动一步,并且它们的索引会减一。但是你的x索引仍然会增加一个,所以现在你引用了列表中的后一个元素:

  1. for循环的第一次迭代:

    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    ...
    
  2. 循环的第二次迭代:

    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    ...
    
  3. 循环的第三次迭代

    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    ...
    
  4. 在循环后至少之前,请勿从列表中删除条目;你不需要在循环中删除它们:

    line = []
    current_length = 0
    for i, word in enumerate(words):
        current_length += len(word)
        if current_length > 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)
    

    或者你可以删除单词(从反向列表中删除效率),但是然后使用while循环并测试累积长度:

    line = []
    current_length = 0
    reversed_words = words[::-1]
    while reversed_words:
        l = len(reversed_words[-1])
        if current_length + l > length:
            break
        line.append(reversed_words.pop())
        current_length += l
    words = reversed_words[::-1]
    line = ''.join(line)
    

    但是,如果您尝试将行长包装应用于Python字符串,则可以避免使用textwrap module重新发明该轮。它可以轻松地在最大长度内进行换行:

    wrapped = textwrap.fill(string, length)