2016-08-03 51 views
1

在Python是这样的:“和”和“或”的操作顺序是什么?

def blackjack_check(hand): # hand is a tuple 
    winning_cards = [10,'Jack','Queen','King'] 
    if hand[0] in winning_cards and hand[1] == 'Ace': 
     return True 
    elif hand[0] == 'Ace' and hand[1] in winning_cards: 
     return True 
    else: 
     return False 

与此相同......?

def blackjack_check(hand): # hand is a tuple 
    winning_cards = [10,'Jack','Queen','King'] 
    if (hand[0] in winning_cards and hand[1]=='Ace' or 
     hand[0] == 'Ace' and hand[1] in winning_cards): 
     return True 
    else: 
     return False 

我可以使用第二个代码块而不是第一个吗?它会消除额外的elif声明,而且看起来更清晰。 我的担心是'和'和'或'操作符是如何工作的。这两个'和'比较是分开的,'或'比较它们吗?是否有'和'和'或'的操作顺序? 我运行的代码,它的工作方式,但我想确保我明白如何操作员工作。

+0

''Ace'在手和任何(x在赢得卡片x手[0:2]) –

回答

4

是,第二个代码块相当于第一个。根据the documentationor的优先级低于and。这意味着if语句被评估为

if ((hand[0] in winning_cards and hand[1] == 'Ace') or 
    (hand[0] == 'Ace' and hand[1] in winning_cards)): 

这就是你想要的。

你可以返回布尔表达式的结果,缩短了代码:

def blackjack_check(hand): 
    winning_cards = [10, 'Jack', 'Queen', 'King'] 
    return (hand[0] in winning_cards and hand[1] == 'Ace' or 
      hand[0] == 'Ace' and hand[1] in winning_cards) 
0

通常的建议是,如果你不知道,那么你的读者可能不知道,如果你使用括号,每个人都会更好。

if ((hand[0] in winning_cards and hand[1]=='Ace') or 
    (hand[0] == 'Ace' and hand[1] in winning_cards)): 

虽然你可以尝试其他的制剂,如

if (any(card == 'Ace' for card in hand) and 
    any(card in winning_cards for card in hand)): 

或写一个辅助函数,并使用

if hascard(hand, ('Ace',)) and hascard(hand, winning_cards): 
2

vaultah's answer地址,您的实际问题完美 - 他们应得的给予好评和复选标记。

但我认为在你正在学习的每种语言中编程二十一点是一个很好的理解它的好方法,所以我把代码放在一起展示了实现二十一点测试的不同方法。更多的教育目的,而不是真正回答你的问题:

# Note: sometimes an Ace should be 1, but when checking for blackjack you can always 
# consider it 11 
def card_value(c): 
    if isinstance(c, int): 
     return c 
    elif c in ['Jack', 'Queen', 'King']: 
     return 10 
    elif c == 'Ace': 
     return 11 

def blackjack_check(hand): 
    hand_value = sum(card_value(c) for c in hand) 
    return hand_value == 21 

print(blackjack_check((2, 10)))    # False 
print(blackjack_check((10, 10)))   # False 
print(blackjack_check((2, 'Ace')))   # False 
print(blackjack_check(('King', 'Jack'))) # False 
print(blackjack_check(('King', 'Ace')))  # True 
print(blackjack_check(('Ace', 'Queen'))) # True 

如果我今天来实现它,卡和手会课,并且有会是一个Hand.is_blackjack()方法,如:

import random 

class Card: 
    NAMES = {1: 'Ace', 11:'Jack', 12:'Queen', 13:'King'} 
    def __init__(self, pips, suit): 
     self.pips = pips 
     self.suit = suit 

    def __repr__(self): 
     name = Card.NAMES.get(self.pips, "%d" % self.pips) 
     return "%s of %s" % (name, self.suit) 

    def value(self, ace_hi=True): 
     # Handle Ace 
     if self.pips == 1: 
      return 11 if ace_hi else 1 
     return min(self.pips, 10) 

class Hand(list): 
    def is_blackjack(self): 
     hand_value = sum(c.value() for c in self) 
     return hand_value == 21 

CARDS = [Card(p,s) for p in range(1,14) for s in ['Spades', 'Hearts', 'Clubs', 'Diamonds']] 

h = Hand(random.sample(CARDS, 2)) 

print("Hand:") 
for c in h: 
    print(" %s" % c) 

print("Blackjack? %s" % h.is_blackjack()) 

示例:

 
Hand: 
    Jack of Spades 
    Ace of Spades 
Blackjack? True 

Hand: 
    Queen of Spades 
    9 of Diamonds 
Blackjack? False 

对不起,这是愚蠢的非答案,但这些只是想法不同的想法。不要担心,如果他们在你的头上,你会到达那里。

+0

谢谢你,我真的很感谢你的回答,这真的很有帮助。我很好奇你如何使用你的课程。它看起来像你使用Python3,因为你的打印语句......当你定义Card类时,我注意到你没有括号后面的参数,那只是一个python2 vs 3的东西吗?另外,你使用list作为Hand类的参数...这是否意味着你计划将一个列表对象传入该类? – Chris

+0

我看到... random.sample()返回一个列表对象,然后你可以传入Hand类 – Chris

+0

@Chris你是指'class Card:'这一行吗?这只是意味着没有明确的超类,Card'应该扩展。另一方面,'Hand'扩展了标准的'list'类。我确实在Python 3中编写了这个代码,在Python 2中,您可能希望使用'class Card(object):'作为良好实践,但我不确定是否有必要。对于第二个问题,'class Hand(list):'意味着我希望'Hand'完全像列表一样操作(索引,'.append()'方法等),除非我定义。在这里,我为这个类添加了一个'is_blackjack()'方法。减去那个方法,'Hand'实例... – jedwards