>>> s = 'AAAAAAAAAAAAAAAAAAA'
>>> s.count(s[0]) == len(s)
True
这不会短路。短路的版本是:>>> all(x == s[0] for x in s)
True
但是,我有一种感觉,由于优化了C实现,非短路版本可能在某些字符串上执行得更好(取决于大小等)
下面是一个简单的timeit脚本,用于测试发布的其他一些选项:import timeit
import re
def test_regex(s,regex=re.compile(r'^(.)\1*$')):
return bool(regex.match(s))
def test_all(s):
return all(x == s[0] for x in s)
def test_count(s):
return s.count(s[0]) == len(s)
def test_set(s):
return len(set(s)) == 1
def test_replace(s):
return not s.replace(s[0],'')
def test_translate(s):
return not s.translate(None,s[0])
def test_strmul(s):
return s == s[0]*len(s)
tests = ('test_all','test_count','test_set','test_replace','test_translate','test_strmul','test_regex')
print "WITH ALL EQUAL"
for test in tests:
print test, timeit.timeit('%s(s)'%test,'from __main__ import %s; s="AAAAAAAAAAAAAAAAA"'%test)
if globals()[test]("AAAAAAAAAAAAAAAAA") != True:
print globals()[test]("AAAAAAAAAAAAAAAAA")
raise AssertionError
print "WITH FIRST NON-EQUAL"
for test in tests:
print test, timeit.timeit('%s(s)'%test,'from __main__ import %s; s="FAAAAAAAAAAAAAAAA"'%test)
if globals()[test]("FAAAAAAAAAAAAAAAA") != False:
print globals()[test]("FAAAAAAAAAAAAAAAA")
raise AssertionError
在我的机器(OS-X 10.5.8,core2duo,python2.7.3)上,有着这些特制的(短)字符串,str.count抽烟set和all,比str.replace稍微强一点,但被str.translate淘汰,而strmul目前处于领先地位:WITH ALL EQUAL
test_all 5.83863711357
test_count 0.947771072388
test_set 2.01028490067
test_replace 1.24682998657
test_translate 0.941282987595
test_strmul 0.629556179047
test_regex 2.52913498878
WITH FIRST NON-EQUAL
test_all 2.41147494316
test_count 0.942595005035
test_set 2.00480484962
test_replace 0.960338115692
test_translate 0.924381017685
test_strmul 0.622269153595
test_regex 1.36632800102
时间安排可能会有点(甚至显著?)不同的系统和不同的字符串之间是不同的,所以用一个您计划传递的实际字符串是值得研究的。
最后,如果你找到了all足够长的最佳条件,并且字符串足够长,那么你可能需要考虑这个条件。这是一个更好的算法。。。我会避免使用set解决方案,因为我看不出任何情况下它可能会击败count解决方案。
如果内存可能是一个问题,那么您需要避免str.translate、str.replace和strmul,因为它们会创建第二个字符串,但是现在这通常不是一个问题。