【问题标题】:If, Elif, Confusion [duplicate]如果,Elif,混乱[重复]
【发布时间】:2013-02-27 06:37:08
【问题描述】:

在编写二十一点脚本时,我遇到了一些关于如何使用“if”、“elif”和“else”语句的困惑。我在这里查看了有关该主题的大多数帖子,用谷歌搜索了它,但仍然感到困惑。 . .我确实了解到,如果使用“elif”而不是重复“if”语句,则当“elif”语句(或其中一个)评估为 True 时,代码将短路。这实际上让我更加困惑(尽管我理解使用“elif”和短路时会发生什么的概念)。第一个 5 'if' 语句说明了这一点。如果我使用 'elif' 而不是 'if',如果玩家和庄家都击中 21,代码可能永远不会达到最后一个条件。。 . 不过,在此之后,似乎我可以使用“elif”语句,或者保持原样。 . .所以,我的问题是,我在 main() 的其余部分是否正确使用了它们?如果没有,你会怎么做?非常感谢。

# current working version - - - 02/26/2013
# Notes: Nees to fix Ace problem. Ace can be 11 or 1.

import random
import os

def main():
    print "Welcome To Python Blackjack. [H] Is For A Hit, [S] Is To Stand, [Q] To       Quit.\n"
    c = ""    # Hit, Stand or Quit Variable.
    player = deal_cards()    # deal player
    dealer = deal_cards()    # deal dealer
    print "< ---- Player Hand ---->"
    print "Player Hand: ", player    
    print "Total Player Hand: ", total_hand(player)    
    print
    print "< ---- Dealer Hand ---->"
    print "Dealer Hand: ", dealer                      
    print "Total Dealer Hand: ", total_hand(dealer)
    print

    if (total_hand(player) == 21):
        print "BLACKJACK! YOU WIN!"
        message()
    if (total_hand(player) > 21):
        print "BUSTED! You Lose"
        message()
    if (total_hand(dealer) == 21):
        print "BLACKJACK! Sorry You Lose! Dealer Wins"               # must use if   statements because elif would fail to reach the tie line.
        message()
    if (total_hand(dealer) > 21):
        print "Dealer Busted! You Win!"
        message()
    if (total_hand(player) == 21) and (total_hand(dealer) == 21):    # must use if       statements because elif would fail to reach this line.
        print "Player And Dealer Tie! Game Goes To Dealer"
        message()

    while (c != "q"):   
        c = raw_input("[H]it [S]tand [Q]uit: ").lower()    
        if (c == "h"):
            hit(player)         
            print ""
            print "Your Cards Are Now: ",player                 
            print "Total For Player Is: ",total_hand(player)
            if (total_hand(player) == 21):
            print "BLACKJACK! You Win!"
            message()
            if (total_hand(player) > 21):
                print "BUSTED! Sorry, You Lose."
                message()
            if (total_hand(dealer) == 21):
                print "BLACKJACK! Sorry You Lose! Dealer Wins."
                message()
            if (total_hand(dealer) > 21):
                print "Dealer Busted! You Win!\n"
                message()
            if (total_hand(dealer) <= 17): 
                hit(dealer)
                print "\nThe Dealer Takes A Card", dealer
                print "For A Total Of: ", total_hand(dealer)
                if (total_hand(dealer) == 21):
                    print "BLACKJACK! Sorry You Lose! Dealer Wins.\n"
                    message()
                if (total_hand(dealer) > 21):
                    print "Dealer Busted! You Win!\n"
                    message()               
            elif (c == "s"):
            if (total_hand(dealer) <= 17):
                hit(dealer)
                print "The Dealer Takes A Card", dealer
                print "For A Total Of: ", total_hand(dealer)
                if (total_hand(dealer) == 21):
                    print "BLACKJACK! Dealer Wins.\n"
                    message()
                if (total_hand(dealer) > 21):
                    print "Dealer Busted! You Win!\n"
                    message()
                if (total_hand(dealer) >= total_hand(player)):
                    print "Sorry, You Lose. Dealer Wins With A Tie\n"
                    message()
                if (total_hand(player) > total_hand(dealer)):
                    print "You Win With The Best Hand!\n"
                    message()
             if (total_hand(player) > total_hand(dealer)):
                print "You Win With The Best Hand!\n"
                message()
            if (total_hand(dealer) > total_hand(player)):
                print "Sorry, You Lose. Dealer Wins\n"
                message()
        else:
            if (c == "q"):
                message()
            else:
                print "Invalid Choice. . .To Quit, Press [Q]"




def deal_cards():
    random1 = random.randint(1,11)
    random2 = random.randint(1,11)
    hand = [random1, random2]
    return hand


def hit(hand):
    newCard = random.randint(1,11)
    hand.append(newCard)
    return hand


def total_hand(hand):
    total = sum(hand)
    return total


def message():
    again = raw_input("Do You Want To Play Again? [Y] For Yes - Press Any Key To Quit:   ").lower()
    if "y" in again:
        main()
    else:
        print "Thanks For Playing"
        os._exit(1)


# main

if __name__ == '__main__':
    main()

【问题讨论】:

  • Python 的elif 等价于else: if。也就是说,如果达到了你之前的条件,它甚至不会检查下一个条件。如果您希望某些条件优先于其他条件,则需要先列出它们!
  • 谢谢。 .我明白你在说什么,我想我什至在我的问题中提到了这一点。我遇到的问题是,您会像我一样使用多个 if 语句,还是将其更改为 if。 .elif,确保首先列出更高优先级的代码?再次感谢您的帮助!
  • 我认为一些答案已经说明了这一点,但是如果您希望同时触发多个if 语句,则应该使用多个语句。如果只发生一次,请使用if/elif/else。我认为您没有在代码中看到通常的行为,因为您已经通过调用 message 来编写它,该调用将永远不会返回。这通常是糟糕的编码风格(循环会更好)。
  • 我明白你在说什么。这正是我一直在寻找的答案。 .再次感谢。

标签: python if-statement


【解决方案1】:

尝试将更具体的条件放在不太具体的条件之前。

例如,如果您从这里更改订单

if (total_hand(player) == 21):
    print "BLACKJACK! YOU WIN!"
    message()
if (total_hand(player) > 21):
    print "BUSTED! You Lose"
    message()
if (total_hand(dealer) == 21):
    print "BLACKJACK! Sorry You Lose! Dealer Wins"                
    message()
if (total_hand(dealer) > 21):
    print "Dealer Busted! You Win!"
    message()
if (total_hand(player) == 21) and (total_hand(dealer) == 21):         
    print "Player And Dealer Tie! Game Goes To Dealer"
    message()

到这里

if (total_hand(player) == 21) and (total_hand(dealer) == 21):         
    print "Player And Dealer Tie! Game Goes To Dealer"
    message()
elif (total_hand(player) == 21):
    print "BLACKJACK! YOU WIN!"
    message()
elif (total_hand(dealer) == 21):
    print "BLACKJACK! Sorry You Lose! Dealer Wins"                
    message()
elif (total_hand(player) > 21):
    print "BUSTED! You Lose"
    message()
elif (total_hand(dealer) > 21):
    print "Dealer Busted! You Win!"
    message()

在您无法使用 elifs 达到语句的所有条件之前,因为满足最后一条语句所需的条件对于第一条或第三条语句都是正确的。

【讨论】:

  • 谢谢。 。好点子。我知道可以按照您的方式进行,但是我的方式错了吗?我想这真的是我的问题。
【解决方案2】:

在这种情况下,使用elif 是绝对安全的。

您是否希望恰好一个出现几个子句?始终使用elif。是否有可能发生多个,不一定相关的子句?使用if

下面是一个示例,说明您需要注意差异的原因:

x = 0
if x < 1:
    do_something()
elif x < 2:
    do_something_else_instead()

这种嵌套有时用于检查x 是否在不同的范围内。但是,如果你不在这里使用elif

x = 0
if x < 1:
    do_something()
if x < 2:
    do_something_else_instead()

现在这两个子句都将被执行,而不是只执行一个,因为如果x 小于一,它也会小于二。这有时可以通过正确检查来避免,如下所示:

x = 0
if x < 1:
    do_something()
if x >= 1 and x < 2:
    do_something_else_instead()

但是,如果 do_something() 也修改了 x,它可能会增加它并将其推送到 1 elif,即保证仅执行其中一个子句,即第一个计算结果为 True 的子句。

【讨论】:

  • 啊哈!我明白你在说什么。无论哪种方式都有危险。十分感谢你的帮助!我会将您的帖子保存在我的笔记中。
【解决方案3】:

if/elif/elif/.../elif/else 序列只是一个 测试,一个接一个地运行直到成功(或者直到所有测试都失败并且else 被执行)。相比之下,ifs 序列只是独立测试序列,每个测试都在不咨询其他测试的情况下运行。

测试顺序很重要!较早的测试在以后的测试之前运行。因此,如果你这样做

def rangetest(n):
    if n >= 40:
        print "Big!"
    elif n >= 25:
        print "Medium!"
    elif n >= 10:
        print "Small!"
    else:
        print "Tiny!"

然后输入rangetest(100) 将始终只打印Big!,即使其余条件都匹配。 (如果我们在这里只使用if 而不是elif,那么我们将得到Big!Medium!Small! 全部打印出来)。


其他答案涉及在您的程序中使用if/elif。我只想指出一件小事。

我会颠倒你程序的逻辑。我不会让main 调用函数message 进而调用main,而是编写一个如下所示的主循环

def main():
    play_game()
    while 1:
        again = raw_input("Do You Want To Play Again? [Y] For Yes - Press Any Key To Quit:   ")
        if 'y' in again.lower():
            play_game()
        else:
            print "Thanks for playing!"
            return # exit main loop

然后play_game 将包含游戏的主要逻辑,return 而不是message()。这简化了您的控制流程,因为您只需退出当前回合(通过使用 return),而不是笨拙地“循环”mainmessage

【讨论】:

  • 太棒了/感谢您的帮助!我会像你和 minopret 建议的那样更改我的代码。
  • 具体来说,你的逻辑函数现在是play_game(或其他任何有意义的),play_game 将使用return(返回到主循环)而不是调用message .这个新的main 以更直接的方式实现了message 的功能,从而暴露了游戏的主要结构(循环一直持续到用户退出)。
  • 我对应该使用您的代码的上下文有点困惑。我了解您的代码,只是不知道如何使用它?我是否应该将主逻辑命名为 play_game(),(而不是 main()),将我的消息函数替换为您的主函数,然后将我使用消息函数的所有地方(在游戏的主逻辑中)替换为“新”主要功能(您创建)?我不认为这是你的意思,所以我想我最好问一下。 。再一次感谢你的帮助。非常感谢。
  • 哎呀,我看到了你的旧评论,所以我的回复高于你的。 HTH。
  • 天哪,真快!你一定一直在等我,哈哈。 . .再次感谢 nneonneo。不胜感激。
【解决方案4】:

如果你修改为在main 中使用while 循环,而不是从message 调用main,我建议你的程序最终会更短更清晰。

Structured programming 是一个曾经但不再有争议的想法,我们使用像 ifelif 这样的条件结构加上像 while 这样的循环,而不是其他控制接下来发生的事情的方法。您从messagemainos.exit 的呼叫采取了与结构化编程不同的策略。通过安排通过message 反复拨打main,你把自己画到了一个角落。事实上,os.exit 只是摆脱那个角落的少数几种方法之一。另一种是抛出异常并在main之外捕获它。

所以试着用这种方式画出来:

def main():
    play()

def play():
    again = True
    while again:
        player = deal_cards()
        dealer = deal_cards()
        print ...
        ...
        game_over = False
        while not game_over
            if (total_hand(player) == 21) and (total_hand(dealer) == 21):
                print "Player And Dealer Tie! Game Goes To Dealer"
                game_over = True
                # You don't need to do anything else here.
            elif total_hand(player) == 21:
                print ...
                game_over = True
            elif total_hand(dealer) == 21:
                print ...
                game_over = True
            elif ...
                print ...
            elif ...
                ...
            else ...
                print ...

            if not game_over:
                c = raw_input("[H]it [S]tand [Q]uit: ").lower()
                if c == "q":
                    game_over = True
                elif c == "h":
                    hit(player)
                    # You don't need to do anything else here.
                else:
                    ...

        answer = raw_input("Do You Want To Play Again? [Y] For Yes - Press Any Key To Quit:   ").lower()
        again = ("y" in answer)

(请忽略这个给专家的说明,只是因为 Stack Overflow 这里有很多:我知道结构化编程的有趣替代方案,包括递归、适当的尾调用和蹦床。对于这个特定的问题,我建议他们不是下一步。)

【讨论】:

  • ...?这真是一个令人困惑的答案。
  • @nneonneo 你在那个程序中读过def message() 吗?
  • 大声笑,谢谢你的建议。我会好好看看你说的话,看看我是否可以改进我的代码。我实际上正在寻找这样的建议(除了我原来的问题)。 .这实际上是我用 Python(或任何语言)编写的第一个脚本。 . .minopret,用你的话告诉我 message() 函数到底出了什么问题?大声笑,我想学习!感谢您的帮助。
  • 我不知道。这是一个很棒的第一个程序。当然,我可以试着想想还能说什么。你的message 函数没有错。但它非常不寻常。我要告诉你的是,你不需要很了解,但这有点酷:有一种编程风格叫做“连续传递风格”(CPS),其中每个方法都像你的message方法。每个方法都以调用另一个方法结束,并且没有方法到达其结束或调用return 语句。几乎没有人使用甚至知道 CPS,除非他们正在编写编译器或教授计算机科学。
  • 你说过这是你的第一个程序吗?好吧,我希望变量againgame_over 的工作原理很明显,但它们可能看起来有点奇怪。它们被称为旗帜。有些人尽量减少使用标志。我认为标志是可以的,不值得为了避免它们而扭曲。我会确保以非常简单的方式使用每个标志。否则可能很难理解代码将遵循哪条路径。
【解决方案5】:

您的代码的一个主要问题是您应该首先检查平局,否则您的玩家将被宣布为获胜者。

对于您的代码,使用ifelif 实际上并没有什么不同。这是因为message() 函数实际上从未返回:它要么退出程序,要么递归调用main()。这不是好的设计:任何其他阅读您的代码的人都不会期望名为 message() 的函数会执行上述任何一项操作。

我的建议是创建一个函数来检查游戏是否结束并返回一个描述结果的字符串。这是我可以做到的;但是请注意,即使在这里您也可以使用if 而不是elif,因为return 语句无论如何都会退出函数。

def check_game_over(total_player, total_dealer):
    if total_dealer == 21:
        if total_player == 21:
            return "Player And Dealer Tie! Game Goes To Dealer"
        else:
            return "BLACKJACK! Sorry You Lose! Dealer Wins"              
    elif total_player == 21:
        return "BLACKJACK! YOU WIN!"
    elif total_player > 21:
        return "BUSTED! You Lose"
    elif total_dealer > 21:
        return "Dealer Busted! You Win!"
    else:
        return None

【讨论】:

  • 谢谢。 . .我应该使用'elif',还是我这样做的方式好吗?我尝试了几种方法,首先使用'elif',然后我将其更改为当前方式(代码双向工作)。 .我的问题是,我做对了吗?
  • 编辑 - - - 我想补充一下,如果我使用 elif,我理解您关于将领带放在首位的建议。 . .我想我真正的问题是,尽管代码按照我的方式工作,你会使用多个 if 语句还是使用 if。 .elif 代替?一个优秀的程序员(像你和这里的其他人)会做什么?
  • 谢谢珍妮。我接受了你的建议。
  • 问题 Janne:你说 message() 函数设计得不好。这仅仅是因为我将其命名为(“任何其他阅读您的代码的人都不会期望名为 message() 的函数执行这些操作”)还是完全不同的原因?只是想学习,再次感谢。
  • @ChrisKavanagh 另一件事是,当人们看到一个函数调用时,人们期望它返回并从下一行继续执行。您的message() 没有返回,这使您的程序难以分析。
【解决方案6】:

不,有几个小的缩进错误,最后,您可以使用 elif 语句。这是您的代码的外观。

def main():
    print "Welcome To Python Blackjack. [H] Is For A Hit, [S] Is To Stand, [Q] To       Quit.\n"
    c = ""    # Hit, Stand or Quit Variable.
    player = deal_cards()    # deal player
    dealer = deal_cards()    # deal dealer
    print "< ---- Player Hand ---->"
    print "Player Hand: ", player    
    print "Total Player Hand: ", total_hand(player)    
    print
    print "< ---- Dealer Hand ---->"
    print "Dealer Hand: ", dealer                      
    print "Total Dealer Hand: ", total_hand(dealer)
    print

    if (total_hand(player) == 21):
        print "BLACKJACK! YOU WIN!"
        message()
    if (total_hand(player) > 21):
        print "BUSTED! You Lose"
        message()
    if (total_hand(dealer) == 21):
        print "BLACKJACK! Sorry You Lose! Dealer Wins"               # must use if   statements because elif would fail to reach the tie line.
        message()
    if (total_hand(dealer) > 21):
        print "Dealer Busted! You Win!"
        message()
    if (total_hand(player) == 21) and (total_hand(dealer) == 21):    # must use if       statements because elif would fail to reach this line.
        print "Player And Dealer Tie! Game Goes To Dealer"
        message()

    while (c != "q"):   
        c = raw_input("[H]it [S]tand [Q]uit: ").lower()    
        if (c == "h"):
            hit(player)         
            print ""
            print "Your Cards Are Now: ",player                 
            print "Total For Player Is: ",total_hand(player)
            if (total_hand(player) == 21):
            print "BLACKJACK! You Win!"
            message()
            if (total_hand(player) > 21):
                print "BUSTED! Sorry, You Lose."
                message()
            if (total_hand(dealer) == 21):
                print "BLACKJACK! Sorry You Lose! Dealer Wins."
                message()
            if (total_hand(dealer) > 21):
                print "Dealer Busted! You Win!\n"
                message()
            if (total_hand(dealer) <= 17): 
                hit(dealer)
                print "\nThe Dealer Takes A Card", dealer
                print "For A Total Of: ", total_hand(dealer)
                if (total_hand(dealer) == 21):
                    print "BLACKJACK! Sorry You Lose! Dealer Wins.\n"
                    message()
                if (total_hand(dealer) > 21):
                    print "Dealer Busted! You Win!\n"
                    message()               
        elif (c == "s"):
            if (total_hand(dealer) <= 17):
                hit(dealer)
                print "The Dealer Takes A Card", dealer
                print "For A Total Of: ", total_hand(dealer)
                if (total_hand(dealer) == 21):
                    print "BLACKJACK! Dealer Wins.\n"
                    message()
                if (total_hand(dealer) > 21):
                    print "Dealer Busted! You Win!\n"
                    message()
                if (total_hand(dealer) >= total_hand(player)):
                    print "Sorry, You Lose. Dealer Wins With A Tie\n"
                    message()
                if (total_hand(player) > total_hand(dealer)):
                    print "You Win With The Best Hand!\n"
                    message()
             if (total_hand(player) > total_hand(dealer)):
                print "You Win With The Best Hand!\n"
                message()
            if (total_hand(dealer) > total_hand(player)):
                print "Sorry, You Lose. Dealer Wins\n"
                message()
        elif (c == "q"):
            message()
        else:
            print "Invalid Choice. . .To Quit, Press [Q]"

【讨论】:

  • 倒数第二个 if 子句在此示例中没有正确缩进。
  • 是的,当我将代码粘贴到我的帖子中时,它搞砸了。对于那个很抱歉。 . .非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2017-01-08
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-15
  • 2015-05-28
  • 1970-01-01
相关资源
最近更新 更多