>>> 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
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
因为它们会创建第二个字符串,但这些天这通常不是问题。