Pythonic方式生成字符串旋转

时间:2015-11-04 12:00:34

标签: python python-2.7

考虑一个字符串'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

3 个答案:

答案 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用于此特定问题,但它可以应用于此类问题的更复杂版本。这是一个非常有用的,在我看来,未充分利用的工具 - 这就是为什么我把它作为这个问题的答案。