'和'的操作顺序是什么?和'或'?

时间:2016-08-03 03:29:27

标签: python if-statement logical-operators

在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声明,它看起来更干净。 我担心的是'和'和'或'运营商工作。是两个'和#39;比较分开,'或'比较他们?是否有'和'的操作顺序?和'或'? 我运行代码并且它可以双向工作,但我想确保我完全理解运算符的工作原理。

3 个答案:

答案 0 :(得分:4)

是的,第二个代码块等同于第一个代码块。根据{{​​3}},or的优先级低于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)

答案 1 :(得分:2)

vaultah's answer完美地解决了您的实际问题 - 他们应该得到upvote和checkmark。

但是我认为用你正在学习的每种语言编写二十一点都是一种更好理解它的好方法,所以我把代码拼凑在一起以显示实现二十一点测试的不同方法。更多用于教育目的而非实际回答您的问题:

# 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

抱歉愚蠢的不回答,但这些只是想法的不同想法。不要担心,如果他们超过你的头,你会到达那里。

答案 2 :(得分: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):