Generating circular shifts / reduced Latin Squares in Python

前端 未结 7 1209
旧时难觅i
旧时难觅i 2020-12-31 19:38

Was just wondering what\'s the most efficient way of generating all the circular shifts of a list in Python. In either direction. For example, given a list [1, 2, 3, 4

7条回答
  •  别那么骄傲
    2020-12-31 20:20

    The answer by @Bruno Lenzi does not seem to work:

    In [10]: from itertools import cycle
    
    In [11]: x = cycle('ABCD')
    
    In [12]: print [[x.next() for _ in range(4)] for _ in range(4)]
    [['A', 'B', 'C', 'D'], ['A', 'B', 'C', 'D'], ['A', 'B', 'C', 'D'], ['A', 'B', 'C', 'D']]
    

    I give a correct version below, however the solution by @f5r5e5d is faster.

    In [45]: def use_cycle(a):
        x=cycle(a)
        for _ in a:
            x.next()
            print [x.next() for _ in a]
       ....:         
    
    In [46]: use_cycle([1,2,3,4])
    [2, 3, 4, 1]
    [3, 4, 1, 2]
    [4, 1, 2, 3]
    [1, 2, 3, 4]
    
    In [50]: def use_slice(a):
        print [ a[n:] + a[:n] for n in range(len(a)) ]
      ....:     
    
    In [51]: use_slice([1,2,3,4])
    [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
    
    In [54]: timeit.timeit('use_cycle([1,2,3,4])','from __main__ import use_cycle',number=100000)
    Out[54]: 0.4884989261627197
    
    In [55]: timeit.timeit('use_slice([1,2,3,4])','from __main__ import use_slice',number=100000)
    Out[55]: 0.3103291988372803
    
    In [58]: timeit.timeit('use_cycle([1,2,3,4]*100)','from __main__ import use_cycle',number=100)
    Out[58]: 2.4427831172943115
    
    In [59]: timeit.timeit('use_slice([1,2,3,4]*100)','from __main__ import use_slice',number=100)
    Out[59]: 0.12029695510864258
    

    I removed the print statement in use_cycle and use_slice for timing purposes.

提交回复
热议问题