Python 列表推导式筛选非数字字符串

9 投票
2 回答
1183 浏览
提问于 2025-04-18 02:38

从高层次来看,我想实现的目标是:

given a list of words, return all the words that do not consist solely of digits

我最初想到的实现方法是:

import string
result = []
for word in words:
    for each_char in word:
        if each_char not in string.digit:
            result.append(word)
            break
return result

这个方法运行得很好。为了让代码更符合Python的风格,我想到了列表推导式,对吧?所以:

return [word for word in words for char in word if not char in string.digits]

不幸的是,这样做会把每个不是数字的字符都复制一份word到结果里。所以当我用f(['foo'])时,最后得到的结果是['foo', 'foo', 'foo']

有没有什么聪明的方法可以实现我想要的效果呢?我现在的解决方案是写一个is_all_digits函数,然后用[word for word in words if not is_all_digits(word)]。我的理解是,列表推导式可以让这种操作更简洁,而这个辅助函数对我来说已经足够清晰了;我只是好奇有没有更聪明的方法能把它写成一个复合语句。

谢谢!

2 个回答

4
filter(lambda _: not _.isdigit(), iterable)

示例:

>>> list(filter(lambda _: not _.isdigit(), ["hello", "good1", "1234"]))
['hello', 'good1']
14

为什么不直接检查整个字符串是否都是数字呢?

>>> words = ['foo', '123', 'foo123']
>>> [word for word in words if not word.isdigit()]
['foo', 'foo123']

或者,可以换个思路,使用 any() 函数:

>>> [word for word in words if any(not char.isdigit() for char in word)]
['foo', 'foo123']

any() 会在遇到第一个不是数字的字符时就停止,并返回 True

撰写回答