使用通配符键创建Python字典

3
我希望创建一个包含通配符键的Python字典,这个可行吗?
目前,我正在创建一个程序,查找与特定得分类型相关联的点值。例如,与“四条”或“顺子”相关联的点值是多少。问题在于,有几种四条(即“四条(1)”,“四条(2)”等),它们都具有相同的点值。
以下是我到目前为止的内容:
mode_value = {'1-Spot': 100,
              '5-Spot': 500,
              'Three-of-a-Kind-(1)': 300,
              'Three-of-a-Kind-(2)': 200,
              'Three-of-a-Kind-(3)': 300,
              'Three-of-a-Kind-(4)': 400,
              'Three-of-a-Kind-(5)': 500,
              'Three-of-a-Kind-(6)': 600,
              'Four-of-a-Kind-(1)': 1000,
              'Four-of-a-Kind-(2)': 1000,
              'Four-of-a-Kind-(3)': 1000,
              'Four-of-a-Kind-(4)': 1000,
              'Four-of-a-Kind-(5)': 1000,
              'Four-of-a-Kind-(6)': 1000,
              'Five-of-a-Kind-(1)': 2000,
              'Five-of-a-Kind-(2)': 2000,
              'Five-of-a-Kind-(3)': 2000,
              'Five-of-a-Kind-(4)': 2000,
              'Five-of-a-Kind-(5)': 2000,
              'Five-of-a-Kind-(6)': 2000,
                 ...
              'Straight': 1500 }  

鉴于字典中包含包含评分模式的关键字,它将返回该特定模式的值:

In [1]: mode_value['Four-of-a-Kind-(3)']
Out [1]: 1000

这会造成大量重复。例如,当我到达'Four-of-a-Kind-w/Pair-(*)'时,它可以与任意六种四张牌中的任意一种配对,并且可以与任意六种两张牌中的任意一种配对,所有这些都产生相同的得分。
mode_value = {'1-Spot': 100,
              '5-Spot': 500,
              'Three-of-a-Kind-(1)': 300,
              'Three-of-a-Kind-(2)': 200,
              'Three-of-a-Kind-(3)': 300,
              'Three-of-a-Kind-(4)': 400,
              'Three-of-a-Kind-(5)': 500,
              'Three-of-a-Kind-(6)': 600,
              'Four-of-a-Kind-(*)': 1000,
              'Five-of-a-Kind-(*)': 2000,
              'Six-of-a-Kind-(*)': 3000,
              'Three-Pairs-(*)': 1500,
              'Two-Triplets-(*)': 2500,
              'Four-of-a-Kind-w/Pair-(*)': 1500,
              'Straight': 1500 } 

我目前所看到的:

在论坛中搜索只能找到关于在查询字典中使用通配符而非创建字典的问题。(例如:Python中使用通配符访问字典)

另一个问题采用推导式实现类似效果(例如:使用推导式创建Python字典),但是考虑到Python大部分情况下都有更简单的方法,我认为一定会有更简单的方法。

那么,在Python中是否可能实现这个功能呢?这将极大地简化编写其他类型评分代码的过程。


一种创建此字典的方法是不需要手动输入所有排列组合。因为这样做既费时,而且如果我添加、删除或修改其中包含的评分模式,也不容易更改。 - Michael Molter
1
你应该以不同的方式存储数据。我会从修改该函数的输出开始。这不是字典的用途。 - Two-Bit Alchemist
@MichaelMolter,我认为你已经自己解决了这个问题。你想要一个分析手牌的函数。只需创建一个函数,输入手牌类型和牌数(可选),并返回相应的数字即可。每种类型都可以执行必要的数学运算来创建相应的得分值。如果你真的想把它转换成一个dict,那么设置一个循环,包含所有可能的组合,并重复调用该函数,将每个可能的值存储到以tuple为键的dict中。如有必要,我可以详细说明。 - Sunny Patel
可能是使用通配符键匹配迭代字典的重复问题。 - Two-Bit Alchemist
https://dev59.com/IYrda4cB1Zd3GeqPKk01 这个问题与我所问的相反。我不是在寻找带通配符的键,而是在生成带通配符的字典。被调用者将始终提供一个文字搜索键。 - Michael Molter
显示剩余3条评论
2个回答

3

首先,您应该将值分开(并且没有括号):

type = 'Three-of-a-Kind'
mode = '1'

这可以通过解析或以不同方式存储数据来完成。

然后,您可以从稍微不同的角度看待问题。

您正在寻找与type-(mode)type-(*)匹配的键的值。解决方案很简单,只需在匹配时使用正则表达式,如此所示

您的代码可能是:

for key in dict:
    if re.match(type + r'-\((' + mode + r'|\*)\)', key):
        print(dict[key])

这将匹配您当前的密钥格式。

为了更简化正则表达式以更改格式为Four-of-a-Kind1(其中Four-of-a-Kind*是通配符版本):

for key in dict:
    if re.match(type + r'(' + mode + r'|\*)', key):
        print(dict[key])

这个答案在语法上是无效的,也没有多少意义。首先你说要分离存储方式以避免 type-(whatever) 结构,然后你给出了一个解释不清的例子来解析你刚刚说不要做的事情。 - Two-Bit Alchemist
@Two-BitAlchemist,你说得对,我忘记了 r,但是你误解了我的代码的其余部分。我没有解释如何解析字符串(因为这很容易做到)。相反,这是从字典中检索键的方法。我接受关于格式的观点,但我只是按照 OP 的键样式进行操作。我提供了一种更可读的替代格式和正则表达式。 - Laurel
我想你说得对,我确实不理解。我会让懂的人取消我的点赞。我的观点关于你的语法问题并不是缺少原始字符串字面量,而是在你现在的两个for语句后面缺少冒号。 - Two-Bit Alchemist
@Two-BitAlchemist 那部分代码是直接从链接的源代码复制过来的(我也会进行编辑)。我对Python不是很熟悉,所以感谢您的帮助。 - Laurel
我喜欢这个答案符合要求,但利用re模块似乎有点过度。尽管如此,感谢您的贡献。 - Michael Molter

1

根据您提供的输入,可以使用以下可能的函数:

def hand_score(hand, cards=None):
    fixed = {
        "Four-of-a-Kind": 1000,
        "Four-of-a-Kind-w/Pair": 1500,
        "Five-of-a-Kind": 2000,
        "Six-of-a-Kind": 3000,
        "Three-Pairs": 1500,
        "Two-Triplets": 2500,
        "Straight": 1500
        }
    if hand in fixed:
        return fixed[hand]
    if hand == "Three-of-a-Kind":
        return 100 * cards
    if hand.endswith("-Spot"):
        return 100 * int(hand[0])
    return 0

fixed 指的是所有分数固定的手牌类型。


我计划实现与此评论类似的想法。我现在相信没有内置的“通配符”字典键,但是当需要这样的功能时,我将使用类似于您的方法来模拟带有一些附加逻辑的字典。在这种情况下,字典非常小,因此性能不是一个很大的问题,但是当字典更大时,我可以看到这种方法成为主要限制因素。 - Michael Molter
如果你真的想要一个字典,你可以使用这样的函数来生成一个,只要你遍历每种可能的情况并将其保存在某个地方。 - Sunny Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接