只是想知道在Python中生成列表的所有循环移位的最有效方法是什么。在任一方向上。例如,给定一个list [1, 2, 3, 4],我想生成其中一个:
[1, 2, 3, 4]
[[1, 2, 3, 4], [4, 1, 2, 3], [3, 4, 1, 2], [2, 3, 4, 1]]
通过将最后一个元素移到最前面来生成下一个排列,或者:
[[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
下一个排列是通过将第一个元素移到后面来生成的。
第二种情况对我来说稍微有点有趣,因为它导致减小的拉丁方(第一种情况也给出了一个拉丁方,只是没有减小),这就是我正在尝试进行实验性块设计的方法。实际上,它们与第一种情况并没有什么不同,因为它们只是彼此重新排序,但是顺序仍然很重要。
我对第一种情况的当前实现是:
def gen_latin_square(mylist): tmplist = mylist[:] latin_square = [] for i in range(len(mylist)): latin_square.append(tmplist[:]) tmplist = [tmplist.pop()] + tmplist return latin_square
对于第二种情况:
def gen_latin_square(mylist): tmplist = mylist[:] latin_square = [] for i in range(len(mylist)): latin_square.append(tmplist[:]) tmplist = tmplist[1:] + [tmplist[0]] return latin_square
第一种情况似乎对我来说应该是相当有效的,因为它使用pop(),但是在第二种情况下您不能这样做,所以我想听听有关如何更有效地执行此操作的想法。也许有些东西itertools会有所帮助?也许第二种情况是双头队列?
pop()
itertools
对于第一部分,最简洁的方法可能是
a = [1, 2, 3, 4] n = len(a) [[a[i - j] for i in range(n)] for j in range(n)] # [[1, 2, 3, 4], [4, 1, 2, 3], [3, 4, 1, 2], [2, 3, 4, 1]]
第二部分
[[a[i - j] for i in range(n)] for j in range(n, 0, -1)] # [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
尽管我没有做任何计时,但它们也应该比您的代码更有效。