在Python中处理数字模式,最好的方法是什么?

4

我在尝试一个 Python 中的模式

如果 n == 6:

1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4

经过反复思考后,我是这样做的——>

n = 6

for i in range(1,n):
    x = 1
    countj = 0
    for j in range(i,n):
        countj +=1
        print(j,end=" ")
        if j == n-1 and countj < n-1 :
            while countj < n-1:
                print(x , end =" ")
                countj +=1
                x +=1
        
    print()

但我不认为这是最好的方法,我一直在尝试寻找更好的方法,但未能找到合适的方法。所以我来到这里,是否有可能有更好的解决方法?

4个回答

11

我会这样做,使用旋转的deque实例:

>>> from collections import deque
>>> n = 6
>>> d = deque(range(1, n))
>>> for _ in range(1, n):
...     print(*d)
...     d.rotate(-1)
... 
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4

也可以只使用范围切片来编写类似/更短的代码,但是可能有点难理解它的工作原理:

>>> ns = range(1, 6)
>>> for i in ns:
...     print(*ns[i-1:], *ns[:i-1])
... 
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4

您也可以创建一个坐标的数学函数,可能看起来像这样:

>>> for row in range(5):
...     for col in range(5):
...         print((row + col) % 5 + 1, end=" ")
...     print()
... 
1 2 3 4 5 
2 3 4 5 1 
3 4 5 1 2 
4 5 1 2 3 
5 1 2 3 4 

一个使用列表推导式的过于聪明的方法:

>>> r = range(5)
>>> [[1 + r[i - j - 1] for i in r] for j in reversed(r)]
[[1, 2, 3, 4, 5],
 [2, 3, 4, 5, 1],
 [3, 4, 5, 1, 2],
 [4, 5, 1, 2, 3],
 [5, 1, 2, 3, 4]]

more-itertools有这个函数:

>>> from more_itertools import circular_shifts
>>> circular_shifts(range(1, 6))
[(1, 2, 3, 4, 5),
 (2, 3, 4, 5, 1),
 (3, 4, 5, 1, 2),
 (4, 5, 1, 2, 3),
 (5, 1, 2, 3, 4)]

1
你可以使用 itertools.cycle 来生成重复的序列,然后使用 itertools.islice 根据迭代次数切片该序列:
from itertools import cycle, islice
n = 6
for i in range(n - 1):
    print(*islice(cycle(range(1, n)), i, i + n - 1))

这将输出以下内容:
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
4 5 1 2 3
5 1 2 3 4

1
你的“模式”实际上被称为Hankel矩阵,在线性代数中常用。
因此,有一个scipy函数用于创建它们。
from scipy.linalg import hankel
hankel([1, 2, 3, 4, 5], [5, 1, 2, 3, 4])

或者

from scipy.linalg import hankel
import numpy as np

def my_hankel(n):
    x = np.arange(1, n)
    return hankel(x, np.roll(x, 1))

print(my_hankel(6))

输出:

[[1 2 3 4 5]
 [2 3 4 5 1]
 [3 4 5 1 2]
 [4 5 1 2 3]
 [5 1 2 3 4]]

请注意,根据定义,所有 Hankel 矩阵都是对称的。我不确定这种特殊类型是否有一个特殊名称...也许是“拉丁方”Hankel矩阵? :) - wim
@wim 很好的建议。我已经更改了它的名称。 - Bill

0

看到很多涉及Python库的答案。如果您想简单地完成它,这里就是方法。

n = 5
arr = [[1 + (start + i) % n for i in range(n)] for start in range(n)]
arr_str = "\n".join(" ".join(str(cell) for cell in row) for row in arr)
print(arr_str)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接