考虑一个字符串'1234'
。您需要一个生成所有旋转的函数:'1234', '3412', '4123', '2341'
。我创建了一个简单的测试套件:
assert rotations('123') == set(['123', '231', '312'])
assert rotations('111') == set(['111'])
assert rotations('197') == set(['197', '971', '719'])
这样做的pythonic方法是什么?我完成了以下代码
def rotations(num):
str_num = str(num)
result = set()
for mid in xrange(len(str_num)):
result.add(
str_num[mid:] + str_num[:mid]
)
return result
答案 0 :(得分:4)
s='1234'
z = {s[x:]+s[:x] for x in range(len(s))}
答案 1 :(得分:3)
您的第二个示例表明,如果数字是周期性的,您的方法效率不高(例如123123123123)。作为解决方案 - 检查是否已经出现给定的旋转。如果是这样 - 序列是周期性的,你已经发现了所有可区分的旋转,所以只需返回结果:
def rotations(num):
str_num = str(num)
result = set()
for mid in range(len(str_num)):
rot = str_num[mid:] + str_num[:mid]
if rot in result:
return result
else:
result.add(rot)
return result
(我将xrange
更改为range
,因为我使用的是Python 3 - 您当然可以改回来。)
答案 2 :(得分:2)
虽然绝对不是最快或最必要的Pythonic答案,但你可以使用collections.deque
来做到这一点。
from collections import deque
def rotations(s):
s_dq = deque(s)
result = set()
for _ in xrange(len(s_dq)):
s_dq.rotate(1)
result.add(''.join(s_dq))
return result
它通过了所有的示例测试:
def main():
tests = ['123',
'111',
'197']
desired = [set(['123', '231', '312']),
set(['111']),
set(['197', '971', '719'])]
for test, result in zip(tests, desired):
print rotations(test) == result
if __name__ == '__main__':
main()
真
真
真
我不建议您将collections.deque用于此特定问题,但它可以应用于此类问题的更复杂版本。这是一个非常有用的,在我看来,未充分利用的工具 - 这就是为什么我把它作为这个问题的答案。