Python 如何在字典中无顺序地搜索?

Python 如何在字典中无顺序地搜索?,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我想做一个石头剪刀布游戏。 我正在制作一个函数来检查谁赢了。 但是我不想做太多的if-else语句。我在考虑一些逻辑来减少这些 我提出了以下实现方法 moves_dict = {('R', 'P'): 'P', ('R', 'S'): 'R', ('S', 'P'): 'S'} user_comp = ['User', 'Computer'] # item_check = (userMove, computerMove) move_ch

我想做一个石头剪刀布游戏。
我正在制作一个函数来检查谁赢了。
但是我不想做太多的
if-else
语句。我在考虑一些逻辑来减少这些

我提出了以下实现方法

moves_dict = {('R', 'P'): 'P',
              ('R', 'S'): 'R',
              ('S', 'P'): 'S'}

user_comp = ['User', 'Computer']

# item_check = (userMove, computerMove)
move_check = ('R', 'S')

if moves_dict.get(move_check):
    print('Move exists')
    print(
        f"Winner : {user_comp[move_check.index(moves_dict.get(move_check))]}")

elif moves_dict.get(move_check[::-1]):
    print("Rev move exist")
    print(
        f"Winner : {user_comp[move_check.index(moves_dict.get(move_check[::-1]))]}")

else:
    print('Tie')

我首先消除了平局的可能性,然后继续获取值(
winner move
),然后在键中查找其索引。在获得索引后,我正在从
用户\u comp
打印获胜者

正如您所看到的,键值对基本上是
move:winner move
。我同意代码有点不可读,但是

我想知道是否有办法不必使用
elif
语句

我想将其部署在网络摄像头提要上的计算机视觉项目中,因此速度也很重要。

只需一点模:

>>> for user in 'RPS':
        for computer in 'RPS':
            winner = ('RPS'.find(user) - 'RPS'.find(computer)) % 3
            print(f'{user=} {computer=} =>',
                  ('Tie', 'User wins', 'Computer wins')[winner])

user='R' computer='R' => Tie
user='R' computer='P' => Computer wins
user='R' computer='S' => User wins
user='P' computer='R' => User wins
user='P' computer='P' => Tie
user='P' computer='S' => Computer wins
user='S' computer='R' => Computer wins
user='S' computer='P' => User wins
user='S' computer='S' => Tie
要回答有关在字典中无顺序搜索的标题问题,可以使用
frozenset
键而不是元组:

>>> moves_dict = {frozenset('RP'): 'P',
                  frozenset('RS'): 'R',
                  frozenset('SP'): 'S'}
>>> for user in 'RPS':
        for computer in 'RPS':
            winner = moves_dict.get(frozenset((user, computer)))
            print(f'{user=} {computer=} =>', winner)

user='R' computer='R' => None
user='R' computer='P' => P
user='R' computer='S' => R
user='P' computer='R' => P
user='P' computer='P' => None
user='P' computer='S' => S
user='S' computer='R' => R
user='S' computer='P' => S
user='S' computer='S' => None
(虽然这只显示了获胜的一手,而不是谁赢了……我真的不想扩展这一点,因为我还是要使用我的第一个解决方案。)

只是一点模:

>>> for user in 'RPS':
        for computer in 'RPS':
            winner = ('RPS'.find(user) - 'RPS'.find(computer)) % 3
            print(f'{user=} {computer=} =>',
                  ('Tie', 'User wins', 'Computer wins')[winner])

user='R' computer='R' => Tie
user='R' computer='P' => Computer wins
user='R' computer='S' => User wins
user='P' computer='R' => User wins
user='P' computer='P' => Tie
user='P' computer='S' => Computer wins
user='S' computer='R' => Computer wins
user='S' computer='P' => User wins
user='S' computer='S' => Tie
要回答有关在字典中无顺序搜索的标题问题,可以使用
frozenset
键而不是元组:

>>> moves_dict = {frozenset('RP'): 'P',
                  frozenset('RS'): 'R',
                  frozenset('SP'): 'S'}
>>> for user in 'RPS':
        for computer in 'RPS':
            winner = moves_dict.get(frozenset((user, computer)))
            print(f'{user=} {computer=} =>', winner)

user='R' computer='R' => None
user='R' computer='P' => P
user='R' computer='S' => R
user='P' computer='R' => P
user='P' computer='P' => None
user='P' computer='S' => S
user='S' computer='R' => R
user='S' computer='P' => S
user='S' computer='S' => None

(虽然这只显示获胜的一手,而不是谁赢了……但我并不真的想扩展这一点,因为我还是要使用我的第一个解决方案。)

您可以将所有选项都放在字典中,这样一个
get
就可以确定

# total outcomes for game
winner_ops = ["user", "computer", "draw", "invalid"]

# winning moves indexed by (user, computer) selection
moves_dict = {('R', 'P'): 1,
              ('R', 'S'): 0,
              ('S', 'P'): 1}

# reversse the moves for opposite win
moves_dict.update((tuple(reversed(key)), int(not moves_dict[key]))      
    for key in list(moves_dict.keys()))

# add draws
moves_dict.update(((val, val), 2) for val in "PRS")

# test
move_check = ('R', 'S')
winner = moves_dict.get(move_check, 3)
print(winner_ops[winner])

您可以将所有选项都放在字典中,这样一个
get
是确定的

# total outcomes for game
winner_ops = ["user", "computer", "draw", "invalid"]

# winning moves indexed by (user, computer) selection
moves_dict = {('R', 'P'): 1,
              ('R', 'S'): 0,
              ('S', 'P'): 1}

# reversse the moves for opposite win
moves_dict.update((tuple(reversed(key)), int(not moves_dict[key]))      
    for key in list(moves_dict.keys()))

# add draws
moves_dict.update(((val, val), 2) for val in "PRS")

# test
move_check = ('R', 'S')
winner = moves_dict.get(move_check, 3)
print(winner_ops[winner])

再加上三个元组颠倒的条目和赢家颠倒的条目再加上三个元组颠倒的条目和赢家颠倒的条目这真是太神奇了。我从来没有真正注意过模。非常感谢。这是一个很好的解决OP问题的方法——它展示了一个更好的方法来实现同样的结果。但是,它并没有回答这个问题,因此其他人在将来发现这个问题时可能不会觉得答案有帮助@PranavHosangadi嗯,但是你注意到了吗,那不是投票最多的答案,而投票最多的答案正好相反?:-)哦,我不是在抱怨你的回答被接受了。因为SO不仅仅是一个回答提问者问题的论坛——它应该帮助其他可能有相同问题的人通过搜索网络找到这个问题——所以最好回答问题并提出更好的方法,而不仅仅是提出更好的方法。通过这种方式,你可以帮助OP,教育他们,并回答其他可能与OP没有完全相同问题但仍然有相同问题的人。FWIW,在你发布答案几分钟后,我对它投了更高的票,因为它太简单了elegant@PranavHosangadi好吧好吧。。。我添加了一个dict解决方案:-)这真是太棒了。我从来没有真正注意过模。非常感谢。这是一个很好的解决OP问题的方法——它展示了一个更好的方法来实现同样的结果。但是,它并没有回答这个问题,因此其他人在将来发现这个问题时可能不会觉得答案有帮助@PranavHosangadi嗯,但是你注意到了吗,那不是投票最多的答案,而投票最多的答案正好相反?:-)哦,我不是在抱怨你的回答被接受了。因为SO不仅仅是一个回答提问者问题的论坛——它应该帮助其他可能有相同问题的人通过搜索网络找到这个问题——所以最好回答问题并提出更好的方法,而不仅仅是提出更好的方法。通过这种方式,你可以帮助OP,教育他们,并回答其他可能与OP没有完全相同问题但仍然有相同问题的人。FWIW,在你发布答案几分钟后,我对它投了更高的票,因为它太简单了elegant@PranavHosangadi好吧好吧。。。我添加了一个dict解决方案:-)