繁体   English   中英

用Python方式生成字符串旋转

[英]Pythonic way to generate string rotations

考虑字符串'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
s='1234'
z = {s[x:]+s[:x] for x in range(len(s))}

您的第二个示例表明,如果该数字是周期性的(例如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

(自从我使用Python 3以来,我将xrange更改为range -当然可以改回)。

尽管绝对不是最快或不一定是最Python化的答案,但是您可以使用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用于此特定问题,但可以将其应用于类似该问题的更复杂版本。 在我看来,这是一个非常有用且未得到充分利用的工具,这就是为什么我将其作为对此问题的答案的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM