【问题标题】:Why is Python not removing this character?为什么 Python 不删除这个字符?
【发布时间】:2021-12-16 16:19:46
【问题描述】:

这是我第一次接触 Python。我正在学习 Head First Python 书中的一个练习。我正在尝试将一个字符串转换为另一个字符串。 (将“Don't panic!”更改为“on tap”。)首先,我将字符串转换为列表。然后,我在 for 循环中使用 if 语句过滤掉不需要的字母。

不过,我遇到了一些非常奇怪的行为!这是我的代码:

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)

这是我的输出:

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

为什么字母“c”还在?它不在我在 if 语句中使用的数组中,其余字符被过滤掉了。但不是“c”。为什么?

【问题讨论】:

  • 修改您正在迭代的列表(即在for 语句中)通常不是一个好主意。您不太可能获得预期的结果(当您对迭代器等更加熟悉时,您会学到更多)。您最好在第一遍中创建一个可移除字母列表,然后再执行另一个循环,将这些字母从列表中移除。
  • 这能回答你的问题吗? How to remove items from a list while iterating?

标签: python string list for-loop


【解决方案1】:

为什么会有这种行为?

首先,您要删除其生成对象在 for 循环中循环的列表。使列表动态。因此,每当您从列表中删除索引时,可以说 D ,第 0 个索引,然后 [ 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] 这将成为您的列表。

现在由于删除 D 时生成器对象位于索引 0,因此 next(object) 将指向剩余列表的第一个索引。所以这将是'n 值。请注意,它没有在新更新的索引处通过 o。当它通过c 时也会发生这种情况。

在这里验证这是一个结果 代码

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)

结果

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

您可以看到删除值时列表的行为

【讨论】:

    【解决方案2】:

    为了显示我在评论中的建议,这是您的代码,已修改:

    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)
    

    (实际上,最好制作可移除的集合,以消除重复条目,但我将其留作练习。)

    这是我的评论,我应该在这个答案中引用:

    修改您所在的列表通常不是一个好主意 迭代(即在 for 语句中)。你不太可能 得到预期的结果(当你得到更多时你会学到更多 对迭代器等感到满意)。你最好创建一个 第一遍中可移动字母的列表,然后执行另一个循环 将从列表中删除这些字母。

    【讨论】:

    • 或者只是反转它并添加集合中的字符,一次完成。
    【解决方案3】:

    您需要遍历该短语。

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

    结果

    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 pan
    

    问题是在您从列表中删除一个字符后,例如:'D, i' 我们将跳过下一个字符。如果您从 not-in 数组中删除 'o',您可以进行测试。应该对输出没有影响。

    【讨论】:

      猜你喜欢
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-10
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      相关资源
      最近更新 更多