【问题标题】:Removing words containing digits from a given string从给定字符串中删除包含数字的单词
【发布时间】:2015-05-11 03:08:46
【问题描述】:

我正在尝试编写一个简单的程序,从接收到的字符串中删除所有包含数字的单词。

这是我当前的实现:

import re

def checkio(text):

    text = text.replace(",", " ").replace(".", " ") .replace("!", " ").replace("?", " ").lower()
    counter = 0
    words = text.split()

    print words

    for each in words:
        if bool(re.search(r'\d', each)):
            words.remove(each)

    print words

checkio("1a4 4ad, d89dfsfaj.")

但是,当我执行这个程序时,我得到以下输出:

['1a4', '4ad', 'd89dfsfaj']
['4ad']

我不明白为什么'4ad' 会打印在第二行,因为它包含数字并且应该从列表中删除。有什么想法吗?

【问题讨论】:

  • 也添加您的预期输出
  • 您在迭代列表时正在修改列表。请参阅此问题,了解为什么不应该这样做:stackoverflow.com/questions/10812272/…
  • 您到底想完成什么?你的限制和条件是什么?
  • 与其说是约束,不如说是理解为什么会出错。我现在看到我正在修改一个正在迭代的列表,这是有道理的。

标签: python regex list iteration


【解决方案1】:

假设您的正则表达式执行您想要的操作,您可以这样做以避免在迭代时删除。

import re

def checkio(text):

    text = re.sub('[,\.\?\!]', ' ', text).lower()
    words = [w for w in text.split() if not re.search(r'\d', w)]
    print words ## prints [] in this case

另外,请注意我简化了您的 text = text.replace(...) 行。

另外,如果你不需要复用你的text变量,你可以直接用正则来拆分。

import re

def checkio(text):

    words = [w for w in re.split('[,.?!]', text.lower()) if w and not re.search(r'\d', w)]
    print words ## prints [] in this case

【讨论】:

    【解决方案2】:

    如果您要测试字母数字字符串,为什么不使用isalnum() 而不是正则表达式?

    In [1695]: x = ['1a4', '4ad', 'd89dfsfaj']
    
    In [1696]: [word for word in x if not word.isalnum()]
    Out[1696]: []
    

    【讨论】:

      【解决方案3】:

      这可以通过使用re.subre.searchlist_comprehension 来实现。

      >>> import re
      >>> def checkio(s):
              print([i for i in re.sub(r'[.,!?]', '', s.lower()).split() if not re.search(r'\d', i)])
      
      
      >>> checkio("1a4 4ad, d89dfsfaj.")
      []
      >>> checkio("1a4 ?ad, d89dfsfaj.")
      ['ad']
      

      【讨论】:

        【解决方案4】:

        所以显然会发生并发访问错误。即 - 您在遍历数组时删除了一个元素。

        在第一次迭代中,我们有单词 = ['1a4', '4ad', 'd89dfsfaj']。由于 '1a4' 有一个数字,我们将其删除。 现在,words = ['4ad','d89dfsfaj']。但是,在第二次迭代中,当前单词现在是“d89dfsfaj”,我们将其删除。发生的情况是我们跳过了“4ad”,因为它现在位于索引 0 处,而 for 循环的当前指针位于 1。

        【讨论】:

        • re.search 返回一个 re.MatchObject
        猜你喜欢
        • 1970-01-01
        • 2012-03-15
        • 1970-01-01
        • 2019-11-20
        • 1970-01-01
        • 2014-05-20
        • 2018-06-23
        • 2014-02-26
        相关资源
        最近更新 更多