我正在想一种方法,使函数决定大多数选票的选举获胜者,以及一个函数决定赢家通吃的规则。
我的代码如下:_base_dict = {}
def add_state(name: str, votes: dict[str, int]) -> None:
global _base_dict
for name, votes in _base_dict.items():
_base_dict[name] += votes
def winner(college: dict[str, int]) -> str:
global _base_dict
rv = None
bigger_percentage = 0
for state, total_votes in college.items():
majority = total_votes // 2
for name, votes in _base_dict.items():
if votes[state] > majority:
percentage = votes[state] / float(total_votes)
if percentage > bigger_percentage:
bigger_percentage = percentage
rv = name
elif percentage == bigger_percentage:
rv = None
if rv is None:
return "No Winner"
return rv
def clear() -> None:
global _base_dict
_base_dict.clear()
_base_dict.update(_base_dict)
和在测试文件中,我通过以下方式运行函数:
import elections
college = {'Virginia': 13,
'Ohio': 18,
'Minnesota': 10,
'Alabama': 9,
'Maine': 4
}
print(elections.winner({}))
elections.add_state('Virginia', {
'Turing': 15,
'Lovelace': 20,
'Dijkstra': 10
})
elections.add_state('Ohio', {
'Turing': 1,
'Dijkstra': 15
})
elections.add_state('Alabama', {
'Turing': 10,
'Lovelace': 20,
'Dijkstra': 8
})
print(elections.winner(college))
elections.add_state('Minnesota', {
'Lovelace': 10,
'Dijkstra': 30,
})
elections.add_state('Florida', {
'Turing': 10,
'Lovelace': 30,
'Dijkstra': 15
})
print(elections.winner(college))
elections.clear()
elections.add_state('Maine', {
'Turing': 2,
'Dijkstra': 1,
'Lovelace': 5
})
print(elections.winner(college))
我想要的输出是:
No Winner
Lovelace
Dijkstra
Lovelace
但是我一直得到:
No Winner
No Winner
No Winner
No Winner
我不知道我做错了什么。任何帮助都是感激的。编辑:我更喜欢用逻辑来解决这个问题,尽管导入也很受欢迎。
我认为这解决了它:
首先,我建议_base_dict
需要是defaultdict
-所以你可以添加keys
到它没有。像这样:
from collections import defaultdict
_base_dict = defaultdict(lambda: defaultdict(lambda: 0))
这样定义,每次调用_base_dict[<some state name>]
时,如果该状态名还不是_base_dict
中的键,则该键被添加到_base_dict
中,并且分配给该键的值成为另一个defaultdict
,其键将是候选名称,并且该状态的投票计数将从0
开始。
其次,我对global _base_dict
业务感到不舒服-这可能更多地说明了我而不是你的代码,但为了保持我的理智,我已经通过在开始定义_base_dict
来解决它,然后在add_state
和winner
的每次调用时将其传递给它们。add_state
接收_base_dict
,修改它,然后返回它。这可能会让函数式编程爱好者疯狂——我很抱歉——我相信如果给我更多的时间,我可以想出一些更优雅的东西。
def add_state(statename: str, statevotes: dict, _base_dict: dict) -> dict:
for candidatename, candidatevotes in statevotes.items():
_base_dict[statename][candidatename] += candidatevotes
return _base_dict
winner
然后接受college
(keys
和values
的状态名称分别为dict
和int
)和_base_dict
(上面已经定义了)。我已经重写了winner
如下:
def winner(college: dict, _base_dict: dict) -> str:
rv = None
bigger_percentage = 0
for state, total_votes in college.items():
majority = total_votes // 2
for candidatename, candidatevotes in _base_dict[state].items():
if candidatevotes > majority:
percentage = candidatevotes / float(total_votes)
if percentage > bigger_percentage:
bigger_percentage = percentage
rv = candidatename
elif percentage == bigger_percentage:
rv = None
if rv is None:
return "No Winner"
return rv
我承认我并没有深入思考这里的计票逻辑,我只是简单地改编了你的原始代码来适应我在这里描述的变化。
最后,重新定义clear
以接受_base_dict
并返回它,如下所示:
def clear(_base_dict: dict) -> dict:
_base_dict.clear()
_base_dict.update(_base_dict)
return _base_dict
将它们放在一起并运行脚本的其余部分:
college = {'Virginia': 13,
'Ohio': 18,
'Minnesota': 10,
'Alabama': 9,
'Maine': 4
}
print(winner(college,_base_dict))
_base_dict = add_state('Virginia', {'Turing': 15,
'Lovelace': 20,
'Dijkstra': 10},
_base_dict)
_base_dict = add_state('Ohio', {'Turing': 1,
'Dijkstra': 15
},
_base_dict)
_base_dict = add_state('Alabama', {'Turing': 10,
'Lovelace': 20,
'Dijkstra': 8},
_base_dict)
print(winner(college, _base_dict))
_base_dict = add_state('Minnesota', {'Lovelace': 10,
'Dijkstra': 30,},
_base_dict)
_base_dict = add_state('Florida', {'Turing': 10,
'Lovelace': 30,
'Dijkstra': 15},
_base_dict)
print(winner(college, _base_dict))
_base_dict = clear(_base_dict)
_base_dict = add_state('Maine', {'Turing': 2,
'Dijkstra': 1,
'Lovelace': 5},
_base_dict)
print(winner(college, _base_dict))
我们得到:
No Winner
Lovelace
Dijkstra
Lovelace
如你所料
绘制出数据结构总是有帮助的,这样可以减少混淆。这个问题可以通过向字典中添加一个键来解决,如果还没有键的话,我们可以直接用新数据更新字典。
_base_dict = {}
'''
'Turing': 'State1': Votes , 'State2': Votes, ...
'Lovelace': 'State': Votes , ...
'Dijkstra': ...
'''
class elections:
def add_state(state: str, data: dict[str, int]) -> None:
global _base_dict
for name, votes in data.items():
if(_base_dict.get(name) == None):
_base_dict[name] = {state: votes}
_base_dict[name].update({state: votes})
def winner(college: dict[str, int]) -> str:
global _base_dict
rv = None
bigger_percentage = 0
for state, total_votes in college.items():
majority = total_votes // 2
for name, votes in _base_dict.items():
# print(f"name:{name} votes:{votes}n")
# print(f"state:{state} total_votes:{total_votes}")
try:
if votes[state] > majority:
percentage = votes[state] / float(total_votes)
if percentage > bigger_percentage:
bigger_percentage = percentage
rv = name
elif percentage == bigger_percentage:
rv = None
except:
pass
if rv is None:
return "No Winner"
return rv
def clear() -> None:
global _base_dict
_base_dict.clear()
_base_dict.update(_base_dict)
college = {'Virginia': 13,
'Ohio': 18,
'Minnesota': 10,
'Alabama': 9,
'Maine': 4
}
print(elections.winner({}))
elections.add_state('Virginia', {
'Turing': 15,
'Lovelace': 20,
'Dijkstra': 10
})
elections.add_state('Ohio', {
'Turing': 1,
'Dijkstra': 15
})
elections.add_state('Alabama', {
'Turing': 10,
'Lovelace': 20,
'Dijkstra': 8
})
print(elections.winner(college))
elections.add_state('Minnesota', {
'Lovelace': 10,
'Dijkstra': 30,
})
elections.add_state('Florida', {
'Turing': 10,
'Lovelace': 30,
'Dijkstra': 15
})
print(elections.winner(college))
elections.clear()
elections.add_state('Maine', {
'Turing': 2,
'Dijkstra': 1,
'Lovelace': 5
})
print(elections.winner(college))
No Winner
Lovelace
Dijkstra
Lovelace