【问题标题】:Filtering out strings that only contains digits and/or punctuation - python过滤掉仅包含数字和/或标点符号的字符串 - python
【发布时间】:2014-03-08 22:21:58
【问题描述】:

我只需要过滤掉只包含数字和/或一组固定标点符号的字符串。

我尝试检查每个字符,然后对布尔条件求和以检查它是否等于len(str)。有没有更pythonic的方式来做到这一点:

>>> import string
>>> x = ['12,523', '3.46', "this is not", "foo bar 42", "23fa"]
>>> [i for i in x if [True if j.isdigit() else False for j in i] ]
['12,523', '3.46', 'this is not', 'foo bar 42']
>>> [i for i in x if sum([True if j.isdigit() or j in string.punctuation else False for j in i]) == len(i)]
['12,523', '3.46']

【问题讨论】:

  • 你确定你不是真的的意思是“我需要找到可以表示数字的字符串,但是float 等不起作用,因为我也想允许逗号作为千位分隔符”?
  • 是的,我稍后会需要它,但两层过滤也会捕获法律文档中的数字索引(例如x = ["chapter", "1.2.3.5"]

标签: python string digit punctuation


【解决方案1】:

使用all和生成器表达式,不用计算,比较长度:

>>> [i for i in x if all(j.isdigit() or j in string.punctuation for j in i)]
['12,523', '3.46']

顺便说一句,上面和 OP 的代码将包含仅包含标点符号的字符串。

>>> x = [',,,', '...', '123', 'not number']
>>> [i for i in x if all(j.isdigit() or j in string.punctuation for j in i)]
[',,,', '...', '123']

要解决这个问题,请添加更多条件:

>>> [i for i in x if all(j.isdigit() or j in string.punctuation for j in i) and any(j.isdigit() for j in i)]
['123']

您可以通过将 string.punctuation 的结果存储在一个集合中来加快速度。

>>> puncs = set(string.punctuation)
>>> [i for i in x if all(j.isdigit() or j in puncs for j in i) and any(j.isdigit() for j in i)]
['123']

【讨论】:

  • 您可以通过将string.punctuation 的结果存储在set 中来加快速度。
  • @FrerichRaabe,感谢您的评论。我添加了你的评论。
【解决方案2】:

您可以使用预编译的正则表达式来检查这一点。

import re, string
pattern = re.compile("[\d{}]+$".format(re.escape(string.punctuation)))
x = ['12,523', '3.46', "this is not", "foo bar 42", "23fa"]
print [item for item in x if pattern.match(item)]

输出

['12,523', '3.46']

@falsetru 的解决方案和我的解决方案之间的一点时间比较

import re, string
punct = string.punctuation
pattern = re.compile("[\d{}]+$".format(re.escape(string.punctuation)))
x = ['12,523', '3.46', "this is not", "foo bar 42", "23fa"]

from timeit import timeit
print timeit("[item for item in x if pattern.match(item)]", "from __main__ import pattern, x")
print timeit("[i for i in x if all(j.isdigit() or j in punct for j in i)]", "from __main__ import x, punct")

在我的机器上输出

2.03506183624
4.28856396675

因此,预编译 RegEx 方法的速度是 allany 方法的两倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-18
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多