【问题标题】:Shortening a function using a dictionary of functions?使用函数字典缩短函数?
【发布时间】:2022-06-19 02:25:15
【问题描述】:

如果我计算 h1、h2,我该如何简化这部分 - 我可以使用某种字典来缩短它吗?

cards = ['1t', '2t', '3t', '4t', '5t', '6t', '7t', '8t', '9t', '10t', '11t', '12t', '13t',
         '1k', '2k', '3k', '4k', '5k', '6k', '7k', '8k', '9k', '10k', '11k', '12k', '13k',
         '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s', '11s', '12s', '13s',
         '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', '10p', '11p', '12p', '13p']

winn = {0: 'nothing', 1: 'one pair', 2: 'two pairs', 3: 'three of a kind', 4: 'straight', 5: 'flush',
        6: 'full house', 7: 'four of a kind', 8: 'straight flush', 9: 'royal flush'}

from random import choice


def hands():
    hand1, hand2 = [], []
    for i in range(5):
        x = choice(cards)
        hand1.append(x)
        cards.remove(x)
        y = choice(cards)
        hand2.append(y)
        cards.remove(y)
    return hand1, hand2


def check_royal_flush(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    if check_flush(hand) and check_straight(hand) and set(num) == {1, 10, 11, 12, 13}:
        return True
    return False


def check_straight_flush(hand):
    if check_flush(hand) and check_straight(hand):
        return True
    return False


def check_four_of_a_kind(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 4}:
        return True
    return False


def check_full_house(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {2, 3}:
        return True
    return False


def check_flush(hand):
    suits = [i[1] if len(i) < 3 else i[2] for i in hand]
    if len(set(suits)) == 1:
        return True
    return False


def check_straight(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if sum(nn) == 5 and (max(num) - min(num) == 4):
        return True
    else:
        if set(num) == {1, 10, 11, 12, 13}:  # sprawdzanie dla asa
            return True
    return False


def check_three_of_a_kind(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 3}:
        return True
    return False


def check_two_pairs(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 2} and sum(nn) == 9:
        return True
    return False


def check_one_pair(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 2} and sum(nn) == 7:
        return True
    return False


def check_winner():
    hand1 = hands()[0]
    hand2 = hands()[1]
    print(f"player one hand{hand1}")
    print(end="\n")
    print(f"player two hand{hand2}", end='\n')
    print(end="\n")
    h1, h2 = 0, 0
    num1 = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand1]
    num2 = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand2]
    if check_royal_flush(hand1):
        h1 = 9
    if check_royal_flush(hand2):
        h2 = 9
    elif check_straight_flush(hand1):
        h1 = 8
    elif check_straight_flush(hand2):
        h2 = 8
    elif check_four_of_a_kind(hand1):
        h1 = 7
    elif check_four_of_a_kind(hand2):
        h2 = 7
    elif check_full_house(hand1):
        h1 = 6
    elif check_full_house(hand2):
        h2 = 6
    elif check_flush(hand1):
        h1 = 5
    elif check_flush(hand2):
        h2 = 5
    elif check_straight(hand1):
        h1 = 4
    elif check_straight(hand2):
        h2 = 4
    elif check_three_of_a_kind(hand1):
        h1 = 3
    elif check_three_of_a_kind(hand2):
        h2 = 3
    elif check_two_pairs(hand1):
        h1 = 2
    elif check_two_pairs(hand2):
        h2 = 2
    elif check_one_pair(hand1):
        h1 = 1
    elif check_one_pair(hand2):
        h2 = 1
    else:
        h1 = 0
        h2 = 0

    if h1 > h2:
        return f"player one wins, with  hand {hand1} he had {winn[h1]}, player two with hand {hand2} had {winn[h2]}"
    elif h1 < h2:
        return f"player two wins, with  hand {hand2} he  had {winn[h2]}, player one with hand {hand1} had {winn[h1]}"
    elif h1 == h2 == 0:
        if max(num1) > sum(num2):
            return f"player one wins, with  hand {hand1} he had higher card, player two with hand {hand2} had {winn[h2]}"
        else:
            return f"player two wins, with  hand {hand2} he had higher card, player one with hand {hand1} had {winn[h1]}"
    elif h1 == h2:
        if sum(num1) > sum(num2):
            return f"player one wins, with  hand {hand1} he had {winn[h1]} with higher cards, player two with hand {hand2} had {winn[h2]}"
        else:
            return f"player two wins, with  hand {hand2} he had {winn[h2]} with higher cards, player one with hand {hand1} had {winn[h1]}"


print(check_winner())

【问题讨论】:

  • 是的。通常可以使代码更短,您可以使用字典。但是在 StackOverflow 上,你应该问更具体的答案。也许这个问题更适合codereview.stackexchange.com

标签: python


【解决方案1】:
if check_royal_flush(hand1):
        h1 = 9
    ...
    else:
        h1 = 0
        h2 = 0

可以改为:

checkers = (
  check_royal_flush,
  check_straight_flush,
  check_four_of_a_kind,
  check_full_house,
  check_flush,
  check_straight,
  check_three_of_a_kind,
  check_two_pairs,
  check_one_pair 
)

def check_winner():
  ...
  result = {"h1": 0, "h2": 0}
  for result_key, hand in (("h1", hand1), ("h2", hand2)):
    score = len(checkers)
    for checker in checkers:
      if checker(hand):
        result[result_key] = score
        break
      score -= 1
  ...

【讨论】:

  • 这并不适用于所有情况。您不能退出循环,因为可能有不止一个匹配项(皇家同花顺也是一对)。如果你打破了你只会找到第一个匹配的模式,而不是最好的评价。
  • 是的。我编辑了答案(反向元组)。我们必须从更大的分数组合开始才能突破。
【解决方案2】:

也许您可以列出函数并遍历它们,使用.get 方法将默认值设置为0

cards = ['1t', '2t', '3t', '4t', '5t', '6t', '7t', '8t', '9t', '10t', '11t', '12t', '13t',
         '1k', '2k', '3k', '4k', '5k', '6k', '7k', '8k', '9k', '10k', '11k', '12k', '13k',
         '1s', '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', '10s', '11s', '12s', '13s',
         '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', '10p', '11p', '12p', '13p']

winn = {0: 'nothing', 1: 'one pair', 2: 'two pairs', 3: 'three of a kind', 4: 'straight', 5: 'flush',
        6: 'full house', 7: 'four of a kind', 8: 'straight flush', 9: 'royal flush'}

from random import choice


def hands():
    hand1, hand2 = [], []
    for i in range(5):
        x = choice(cards)
        hand1.append(x)
        cards.remove(x)
        y = choice(cards)
        hand2.append(y)
        cards.remove(y)
    return hand1, hand2


def check_royal_flush(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    if check_flush(hand) and check_straight(hand) and set(num) == {1, 10, 11, 12, 13}:
        return True
    return False


def check_straight_flush(hand):
    if check_flush(hand) and check_straight(hand):
        return True
    return False


def check_four_of_a_kind(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 4}:
        return True
    return False


def check_full_house(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {2, 3}:
        return True
    return False


def check_flush(hand):
    suits = [i[1] if len(i) < 3 else i[2] for i in hand]
    if len(set(suits)) == 1:
        return True
    return False


def check_straight(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if sum(nn) == 5 and (max(num) - min(num) == 4):
        return True
    else:
        if set(num) == {1, 10, 11, 12, 13}:  # sprawdzanie dla asa
            return True
    return False


def check_three_of_a_kind(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 3}:
        return True
    return False


def check_two_pairs(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 2} and sum(nn) == 9:
        return True
    return False


def check_one_pair(hand):
    num = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand]
    nn = [num.count(i) for i in num]
    if set(nn) == {1, 2} and sum(nn) == 7:
        return True
    return False


def check_winner():
    hand1 = hands()[0]
    hand2 = hands()[1]
    print(f"player one hand{hand1}")
    print(end="\n")
    print(f"player two hand{hand2}", end='\n')
    print(end="\n")
    h1, h2 = 0, 0
    num1 = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand1]
    num2 = [int(i[0]) if len(i) < 3 else int(i[0:2]) for i in hand2]
    
    funcs = {check_royal_flush:9,check_straight_flush:8,check_four_of_a_kind:7,check_full_house:6,check_flush:5,check_straight:4,check_three_of_a_kind:3,check_two_pairs:2,check_one_pair:1}
    for func in (check_royal_flush, check_straight_flush, check_four_of_a_kind, check_full_house, check_flush, check_straight, check_three_of_a_kind, check_two_pairs, check_one_pair):
        if func(hand1):
            h1 = funcs.get(func,0)
        elif func(hand2):
            h2 = funcs.get(func,0)
    if h1 > h2:
        return f"player one wins, with  hand {hand1} he had {winn[h1]}, player two with hand {hand2} had {winn[h2]}"
    elif h1 < h2:
        return f"player two wins, with  hand {hand2} he  had {winn[h2]}, player one with hand {hand1} had {winn[h1]}"
    elif h1 == h2 == 0:
        if max(num1) > sum(num2):
            return f"player one wins, with  hand {hand1} he had higher card, player two with hand {hand2} had {winn[h2]}"
        else:
            return f"player two wins, with  hand {hand2} he had higher card, player one with hand {hand1} had {winn[h1]}"
    elif h1 == h2:
        if sum(num1) > sum(num2):
            return f"player one wins, with  hand {hand1} he had {winn[h1]} with higher cards, player two with hand {hand2} had {winn[h2]}"
        else:
            return f"player two wins, with  hand {hand2} he had {winn[h2]} with higher cards, player one with hand {hand1} had {winn[h1]}"


print(check_winner())

【讨论】:

  • 你测试了吗?对于皇家同花顺,例如这会将其评为一对,因为最后检查的是那一对。使用此代码,您将无法找到最高分数,而是找到最后一个匹配的分数。
【解决方案3】:

下面的内容怎么样:

a_list = [
    (check_one_pair, 1),
    (check_two_pairs, 2),
    ...
    (check_royal_flush, 9)
]
h1, h2 = 0, 0
for func, score in a_list:
    if func(hand1):
        h1 = max(h1, score)
    if func(hand2):
        h2 = max(h2, score)

它不使用字典,而是使用元组列表,因为字典引入的映射不需要仅用于迭代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多