Python 如何检查字符串是否包含不在列表中的字符?
我有个问题。如何检查python字符串是否包含不在给定列表中的字符 以下是列表(集合):Python 如何检查字符串是否包含不在列表中的字符?,python,python-3.x,Python,Python 3.x,我有个问题。如何检查python字符串是否包含不在给定列表中的字符 以下是列表(集合): set(“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789-。) 使用any为字符串的每个字符检入集合 SET=SET(“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzo123456789-。” s=“123#” 打印(任何(x未设置为x英寸s)) 在验证字符串时,我总是遵从正
set(“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz012456789-。)
- 使用
为字符串的每个字符检入集合any
SET=SET(“abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzo123456789-。”
s=“123#”
打印(任何(x未设置为x英寸s))
在验证字符串时,我总是遵从正则表达式
要创建集合,请将集合中的所有字符括在[]
中。
要检查字符串是否包含任何不在集合中的字符,请在开头添加^
。
要检查字符串是否包含一个或多个集合成员,请附加+
根据此信息,检查字符串是否包含除{a,b,c,d}以外的任何字符的正则表达式如下所示:
[^abcd]+
(注意这是区分大小写的)
要在python中使用正则表达式,import re
。re.search(pattern,string,flags=0)
方法将在整个字符串中查找您给出的模式
可以找到有关python中正则表达式的更多信息。可以找到一个简单的正则表达式测试器。您想测试字符串中的字符是否是给定字符集的子集。这在Python中很简单,因为比较不同解决方案的运行时
import timeit
search_strings = [
'"#12"', # short string, early match
'"#1234567"', # longer string, early match
'"1234567#"', # longer string, late match
'"123" * 100 + "#"', # long string, late match
'"123#" * 100', # long string early match
]
algorithms = [
("r.search(s)", 's={};import re; r = re.compile(r"[^-.\w]")'),
("set(s) - SET", 's={};SET=frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._")'),
("any(x not in SET for x in s)", 's={};SET=frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._")'),
("SET.issuperset(s)", 's={};SET=frozenset("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._")'),
]
for alg, setup in algorithms:
print alg
for sstr in search_strings:
print "%35s %.3f" % (sstr[:35], timeit.timeit(alg, setup.format(sstr)))
这将在我的机器上提供以下输出:
r.search(s)
"#12" 0.470
"#1234567" 0.514
"1234567#" 0.572
"123" * 100 + "#" 3.493
"123#" * 100 0.502
set(s) - SET
"#12" 0.566
"#1234567" 1.045
"1234567#" 1.075
"123" * 100 + "#" 7.658
"123#" * 100 10.170
any(x not in SET for x in s)
"#12" 0.786
"#1234567" 0.797
"1234567#" 1.475
"123" * 100 + "#" 27.266
"123#" * 100 1.087
SET.issuperset(s)
"#12" 0.466
"#1234567" 0.864
"1234567#" 0.896
"123" * 100 + "#" 7.512
"123#" * 100 10.199
我们发现正则表达式的解决方案是最快的。将字符串转换为
集
,然后得到两个集之间的差异。如果这不是空的,则字符串包含不在集合中的字符。为什么以“更新问题以便只关注一个问题”的原因结束此操作?第二个问题在哪里?从答案中可以看出,这个问题是明确的。请重新打开。为什么不干脆set(s)-set
?您只需要知道您的字符串是否包含不在s中的字符。使用any可以帮助提前停止。@bjorn取决于字符串。当任何
在第一个非成员处停止时,您的方式总是构建整个集合。因此,您的速度较慢,例如s=“#123456789”
。也许SET.issuperset(s)
是最好的。@HeapOverflow它实际上并不依赖于字符串,唯一的退化情况是非法字符位于长字符串的前三个位置。如果不满足这些条件中的任何一个,例如,如果字符串较短:set(“#12”)-set
比any
版本快约25%。set实现也有一个可预测的运行时,因为它是用C实现的,而any循环是用Python实现的——更不用说set版本更容易理解了。@thebjorn这似乎确实是最快的。也可以使用r“[^-.\w]”
,因为\w
包括数字和下划线。还有set.issuperset
,它接受任何iterable.Nevermind。我认为它会更快,因为它可以在第一个非成员处停止,而不是首先创建整个s
的集合,但我只是检查了一下,然后就完成了。嘎。