如何优化德州扑克初始两张手牌分析的Python实现代码?
Hey there! Great start on your poker hand analyzer—those 169 starting combinations can feel overwhelming at first, but we can clean up that messy if-elif chain with some Python tricks that are easier to maintain, faster to run, and simpler to extend for non-pair hands later.
First, let's fix a small bug in your current code: lines like if rank and rank1 == 13 don't work the way you think. Since you already checked rank == rank1, you only need to check if rank == 13 (the and rank1 ==13 is redundant, and the rank and part is actually checking if rank is non-zero, which it always will be here).
Now, onto the better approach: use dictionaries to map hand characteristics directly to their rankings. Dictionaries let you look up values in constant time (O(1)) instead of checking every condition one by one, and they make it trivial to update rankings or add new hands later.
Step 1: Standardize Your Input
First, let's clean up input handling and normalize the hand so we don't have to worry about input order (e.g., entering K then A vs A then K):
def get_rank_name(rank): # Helper function to convert numeric ranks to readable names (1=2, 13=A) rank_map = { 1: '2', 2: '3', 3: '4', 4: '5', 5: '6', 6: '7', 7: '8', 8: '9', 9: 'T', 10: 'J', 11: 'Q', 12: 'K', 13: 'A' } return rank_map[rank] # Get and clean user input suit1 = input("Enter suit of first card (e.g., H, D, C, S): ").strip().upper() rank1 = int(input("Enter rank of first card (1=2, ..., 13=A): ").strip()) suit2 = input("Enter suit of second card: ").strip().upper() rank2 = int(input("Enter rank of second card: ").strip()) # Normalize the hand: sort ranks so high rank comes first, check for same suit/pair rank_high, rank_low = max(rank1, rank2), min(rank1, rank2) is_same_suit = suit1 == suit2 is_pair = rank1 == rank2
Step 2: Replace if-elif with a Dictionary for Pairs
Instead of writing a condition for every pair, store pair rankings in a dictionary where the key is the rank number, and the value is the ranking string:
# Pair rankings: key = numeric rank, value = ranking fraction pair_rankings = { 13: "1/169", # AA 12: "2/169", # KK 11: "3/169", # QQ 10: "5/169", # JJ 9: "10/169", # TT 8: "17/169", # 99 7: "21/169", # 88 6: "29/169", # 77 5: "36/169", # 66 4: "46/169", # 55 3: "50/169", # 44 2: "52/169", # 33 1: "51/169" # 22 } # Handle pair hands if is_pair: pair_name = f"Pair of {get_rank_name(rank_high)}s" print(f"{pair_name}: {pair_rankings[rank_high]}")
Step 3: Extend to Non-Pair Hands
For non-pair hands (like AK suited vs offsuit), we can use a dictionary with tuples as keys to capture the high rank, low rank, and whether the suits match. This makes it easy to look up exact combinations:
else: # Non-pair rankings: key = (high_rank, low_rank, is_same_suit), value = ranking non_pair_rankings = { (13, 12, True): "3/169", # AK suited (AKs) (13, 12, False): "5/169", # AK offsuit (AKo) (13, 11, True): "4/169", # AQs (13, 11, False): "7/169", # AQo (13, 10, True): "6/169", # AJs (13, 10, False): "9/169", # AJo # Add all other 156 non-pair combinations here } # Get the ranking, or show a placeholder if not yet added hand_name = f"{get_rank_name(rank_high)}{get_rank_name(rank_low)}{'s' if is_same_suit else 'o'}" ranking = non_pair_rankings.get((rank_high, rank_low, is_same_suit), "Ranking not yet defined") print(f"{hand_name}: {ranking}")
Why This Works Better
- Maintainability: If you need to update a ranking or add a new hand, you just edit the dictionary—no digging through a long list of
ifstatements. - Readability: The logic is split into clear sections (input handling, pair checks, non-pair checks) that are easy to follow.
- Scalability: Adding support for edge cases (like suited connectors, or special hand labels) is straightforward with dictionary lookups.
As you add more non-pair combinations, you could even load the rankings from a CSV file instead of hardcoding them, which would make managing all 169 hands even easier!
内容的提问来源于stack exchange,提问作者Arnav H

