38

我需要if用 Python 写这四个。注意它的作用,是在循环中的四种可能状态之间变化:1,0 -> 0,1 -> -1,0 -> 0,-1然后回到第一个。

if [dx, dy] == [1,0]:
    dx, dy = 0, 1
if [dx, dy] == 0, 1:
    dx, dy = -1, 0
if [dx, dy] == [-1, 0]
    dx, dy = 0, -1
if [dx, dy] == [0, -1]:
    dx, dy = 1, 0

任何人都可以建议我更好/更好的方式来写这个吗?

4

5 回答 5

158
dx, dy = -dy, dx

如有疑问,请应用数学。;)

于 2012-02-01T23:12:25.583 回答
56

不可否认,Magnus 的建议是对您提出的问题的正确答案,但一般来说,您希望使用字典来解决以下问题:

statemap = {(1, 0): (0, 1), (0, 1): (-1, 0), (-1, 0): (0, -1), (0, -1): (1, 0)}

dx, dy = statemap[dx, dy]

即使在这种情况下,我也可以认为使用字典更好,因为很明显有四种状态并且它们重复,但很难抗拒所有数学的纯粹之美。

顺便说一句,您问题中的代码有一个错误,并且假设您测试的值是唯一可能的值,则相当于:

dx, dy = 1, 0

错误是您需要elif第二个和后续条件,否则您将继续测试dxdy在更改它们之后。如果它们是1and 0,那么您的所有条件都将为真,并且最终结果相同!如果它们开始为01那么第二个和所有后续条件都将为真,并且您再次以 . 结尾1, 0。等等...

于 2012-02-01T23:11:09.797 回答
31

只是扩展马格努斯的答案。如果您将 [dx, dy] 想象为一个向量,那么您实际上所做的是旋转90 度(或 PI/2)。

要计算这一点,您可以使用以下转换:

二维旋转

在你的情况下转化为:

x = x * cos(90) - y * sin(90)
y = x * sin(90) + y * cos(90)

由于我们将sin(90) = 1cos(90) = 0简化为:

x, y = -y, x

你有它!

于 2012-02-08T16:22:22.497 回答
18

您正在使用的值似乎是一个连续旋转的单位向量 - 换句话说,一个phasor复数是坐标,所以:

# at initialization
phase = 1
# at the point of modification
phase *= 1j
dx, dy = phase.real, phase.imag

假设我对 dx,dy 值含义的解释是正确的,这为您提供了额外的灵活性,以防以后您想在每个步骤中旋转一些其他量。

于 2012-02-02T00:42:19.497 回答
6

虽然我会接受 Magnus 的回答,但这是另一种轮换一组值的方法:

def rotate(*states):
    while 1:
        for state in states:
            yield state

for dx, dy in rotate((1, 0), (0, 1), (-1, 0), (0, -1)):
    pass

请注意,循环中应该有一个break地方,for dx, dy否则它将永远不会结束。

于 2012-02-01T23:55:16.843 回答