无需生成所有可能的选票。您可以测试您的实际投票,而无需生成possiblevotes
列表,因为您可以轻松计算现有投票是否可行。
您也只真正计算“留下”选票。m == n
寻找匹配的“坚持下去”投票并不重要,因为任何正确的“坚持下去”投票m.split()[0] == n.split()[0]
也是正确的。所以你不妨放弃第一个计数,只看第二个。
现在您只是在找到最大stay
票数。使用 acollections.Counter()
使计算事情变得更容易:
import collections
vote_counts = collections.Counter(v.split()[0] for v in votes)
maxsat = vote_counts.most_common(1)[0][1] # retrieve the most popular count
这会计算出与您的代码计算出的数字相同的数字,但现在我们只需循环一次投票,并且只计算“留”票。
将此与您的循环进行对比,您首先循环numcats * numdogs
时间,然后循环numcats * numdogs * 2 * len(votes)
时间。那一个因素3 * numcats * numdogs
更大。
如果您必须首先验证投票,您可以使用:
from itertools import ifilter
numcats = int(numcats)
numdogs = int(numdogs)
def validvote(vote):
stay, go = vote.split()
cat, dog = sorted((stay, go))
if (cat[0], dog[0]) != ('C', 'D'):
return False
if not (1 >= int(cat[1:]) >= numcats):
return False
if not (1 >= int(dog[1:]) >= numdogs):
return False
return True
vote_counts = collections.Counter(v.split()[0] for v in ifilter(validvote, votes))
你也可以开始使用go投票:
stay_votes = collections.Counter()
go_votes = collections.Counter()
for vote in ifilter(validvote, votes):
stay, go = vote.split()
stay_votes[stay] += 1
go_votes[go] += 1
现在您可以简单地从留票数中减去go 票(删除任何降至 0 的票数):
total_votes = stay_votes - go_votes
# Display top 10
for creature, tally in total_votes.most_common(10):
print('{}: {:>#5d}'.format(creature, tally))
当然,你也可以一次性完成计算:
total_votes = collections.Counter()
for vote in ifilter(validvote, votes):
stay, go = vote.split()
total_votes[stay] += 1
total_votes[go] -= 1
但是将投票记录分开可能对以后的分析很有趣。