在Python中使用Dictionaries代替Case / Switch语句

时间:2012-04-29 03:50:21

标签: python random dictionary rubiks-cube

我想随机化一个初始化为完整的rubik立方体(正确边上的所有颜色)。我有移动旋转立方体的函数。我想连续随机选择50个函数来正确随机化。

我正在做这个项目来学习更多关于Python的知识,因为我主要做C ++而且我看到Python没有case / switch,所以我正在尝试字典。当我创建字典时,代码似乎由于某种原因而执行:

def random_cube(self):
    scramble = {    0 : self.up_turn(),
                    1 : self.down_turn(),
                    2 : self.left_turn(),
                    3 : self.right_turn(),
                    4 : self.front_turn(),
                    5 : self.back_turn(),
                    6 : self.up_turn("inverted"),
                    7 : self.down_turn("inverted"),
                    8 : self.left_turn("inverted"),
                    9 : self.right_turn("inverted"),
                    10: self.front_turn("inverted"),
                    11: self.back_turn("inverted")
                }
    for x in range(50):
        i = random.randint(0,11)
        scramble[i]

因此,当我创建这个字典时,由于某种原因(我认为)它似乎贯穿并执行所有11个条目。我似乎无法找到更好的方法,至少比长if / elif语句更优雅。

!编辑:实现这两个建议,这两个函数的(“倒”)标志都没有被任何建议设置。例如,调用1和7都会给我down_turn,但输出显示该标志在它应该在7号时没有设置。

有什么想法吗?

2 个答案:

答案 0 :(得分:16)

当你定义dict时,它实际上调用了函数,并将返回值存储在字典中。要让字典存储对函数的引用,您需要删除尾随括号。如下所示:

scramble = {  0: self.up_turn,
              1: self.down_turn,
              etc.

然后,在底部,拨打scramble[i]()

这将调用没有参数的函数。要处理将“反向”作为参数传递的情况,您可以定义单独的函数,如up_turn_inverted()等,或者您可以让字典存储由函数和参数组成的2-ple,然后调用喜欢scramble[i][0](scramble[i][1])

的东西

从评论中的建议更新: 您还可以使用lambda表达式来定义函数,尤其是需要参数的函数。这基本上等同于定义up_turn_inverted函数,但作为匿名函数就地完成。它看起来像这样:

6: lambda: self.up_turn("inverted")
7: lambda: self.down_turn("inverted")

答案 1 :(得分:2)

我相信这被称为“作为一等值的函数”,这意味着最重要的是你可以将参考函数的标识符作为参数传递给其他函数。

定义字典时,Python解释器会评估函数并将值存储在字典中。要在生成随机数之前将其关闭,请尝试通过不使用括号来存储对字典中函数本身的引用:

def random_cube(self):
    scramble = {    0 : self.up_turn,
                    1 : self.down_turn,
                    2 : self.left_turn,
                    3 : self.right_turn,
                    4 : self.front_turn,
                    5 : self.back_turn,
                    6 : self.up_turn,
                    7 : self.down_turn,
                    8 : self.left_turn,
                    9 : self.right_turn,
                    10: self.front_turn,
                    11: self.back_turn
                }

然后在for循环中调用函数时,你必须区分你传递参数的正常情况和反向情况:

    for x in range(50):
        i = random.randint(0,11)
        if i <= 5:
            scramble[i]()
        else:
            scramble[i]("inverted")

或更简单:

    for x in range(50):
        i = random.randint(0,11)
        scramble[i]( () if i < 6 else ("inverted"))
相关问题