5
if n == 1: return [(-1,),    (1,)]
if n == 2: return [(-1,0),   (1,0),   (0,-1),   (0,1)]
if n == 3: return [(-1,0,0), (1,0,0), (0,-1,0), (0,1,0), (0,0,-1), (0,0,1)]

基本上,返回2n符合上述规范的元组列表。上面的代码适用于我的目的,但我希望看到一个适用于所有 n ∈ ℕ 的函数(仅用于教化)。包括tuple([0]*n)在答案中是我可以接受的。

我正在使用它来生成测量多面体的面方向。对于所有方向,我都可以使用list(itertools.product(*[(0, -1, 1)]*n)),但我无法仅针对面部方向想出如此简洁的东西。

4

5 回答 5

5
def faces(n):
    def iter_faces():
        f = [0] * n
        for i in range(n):
            for x in (-1, 1):
                f[i] = x
                yield tuple(f)
            f[i] = 0
    return list(iter_faces())

>>> faces(1)
[(-1,), (1,)]
>>> faces(2)
[(-1, 0), (1, 0), (0, -1), (0, 1)]
>>> faces(3)
[(-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)]
于 2013-08-07T15:45:01.887 回答
3

我看到这个问题的方式是两个同时交错n大小的移位寄存器

>>> def shift_register(n):
    l1 = (-1,) + (0,)*(n - 1)
    l2 = (1,) +  (0,)*(n - 1)
    while any(l1):
        yield l1
        yield l2
        l1 = (0,) + l1[:-1]
        l2 = (0,) + l2[:-1]


>>> list(shift_register(3))
[(-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)]
于 2013-08-07T15:56:09.930 回答
3

使用的解决方案numpy

>>> a = numpy.identity(3, dtype=int)
>>> numpy.hstack((a, -a)).reshape(6, 3)
array([[ 1,  0,  0],
       [-1,  0,  0],
       [ 0,  1,  0],
       [ 0, -1,  0],
       [ 0,  0,  1],
       [ 0,  0, -1]])
于 2013-08-07T15:57:09.093 回答
3
[tuple(sign * (i == p) for i in range(n)) for p in range(n) for sign in (-1, 1)]

普通for的,没有隐含的boolint等价的:

for p in range(n):
    for sign in (-1, 1):
        yield tuple((sign if i == p else 0) for i in range(n))
于 2013-08-07T15:45:28.730 回答
2
>>> set(itertools.permutations([1] + [0]*(n-1))) | set(itertools.permutations([-1] + [0]*(n-1)))
于 2013-08-07T15:44:52.480 回答