0

我试图为练习编写代码,虽然它可以正常工作,但它看起来很可怕,我想知道是否有人可以帮助我删除任何不必要的东西,并可能只是组合一些功能?

以下是该函数的使用示例:

choices([['YES', 'NO', 'YES', 'YES'], ['NO', 'NO', 'YES', 'NO'], ['YES', 'YES', 'YES', 'YES']])

列表中的每个列表都有四个是/否选项(下面的索引也列出了四个选项,例如绿色、红色、蓝色、黄色;但不一定是四个)。列表中的列表数量是多少人投票。

i = 0
num = 0
total_num = 0
num_choices = len(INDICES)
choices_index = 0
choices_votes = []
choices_votes_num = []
index = 0
total_choices = []
winning_choice = ''
winning_index = 0
while i < len(parameter):
    while num < num_choices:
        for item in parameter:
            choices_votes.append(item[num])
        num += 1
    i += 1
while total_num < len(choices_votes):
    if choices_votes[total_num] == 'YES':
        choices_votes_num.append(1)
        total_num += 1
    elif choices_votes[total_num] == 'NO':
        choices_votes_num.append(0)
        total_num += 1
while choices_index < len(choices_votes_num):
    count = int(len(choices_votes_num) / num_choices)
    total = 0
    total = sum(choices_votes_num[choices_index:(choices_index + count)])
    total_choices.append(total)
    choices_index = choices_index + count
for score in total_choices:
    winning_index = max(total_choices)
    winning_choice = INDEX_TO_NAME[total_choices.index(winning_index)]
return winning_choice, total_choices

INDEX_TO_NAME只是一个字典,用于将索引连接到选择(颜色)。

基本上,代码应该将每个“是”计为 1 分,每个“否”计为 0 分,将每个可用选项的总分相加,然后返回总分和获胜者。

4

1 回答 1

4

让我们从:

c = [['YES', 'NO', 'YES', 'YES'],
     ['NO', 'NO', 'YES', 'NO'],
     ['YES', 'YES', 'YES', 'YES']]

INDICES = ['red', 'green', 'blue', 'yellow']

由于您一直在使用INDICES您的民意调查,我们可以假设答案将始终与INDICES.

我们可以利用zip来重组这些数据:

zip(*c)
#[('YES', 'NO', 'YES'),
# ('NO', 'NO', 'YES'),
# ('YES', 'YES', 'YES'),
# ('YES', 'NO', 'YES')]

这扩展了参数的答案并将它们重新组合以按实际索引进行分组。所以第一个索引是“红色”,第二个是“绿色”,等等

现在我们可以再次压缩以将它们与索引结合起来:

results = zip(INDICES, zip(*c))
#[('red', ('YES', 'NO', 'YES')),
# ('green', ('NO', 'NO', 'YES')),
# ('blue', ('YES', 'YES', 'YES')),
# ('yellow', ('YES', 'NO', 'YES'))]

我们可以循环results,简单地计算“YES”的出现次数:

totals = [(ind, answers.count('YES')) for ind,answers in results]
#[('red', 2), ('green', 1), ('blue', 3), ('yellow', 2)]

所以这里我们有总数。我们可以将它传递给一个调用,max让它告诉我们哪一个是赢家:

max(totals, key=lambda x: x[1])
#('blue', 3)

max默认情况下会查看第一个索引,所以我们可以传递一个key函数来指示它拉索引1。它告诉我们蓝色是赢家。

为了更高效,我们实际上可以将生成器传递给max

totals = ((ind, answers.count('YES')) for ind,answers in results)
#<generator object <genexpr> at 0x102581fa0>
max(totals, key=lambda x: x[1])
#('blue', 3)

最后的单个语句可以这样写:

max(((ind, answers.count('YES')) for (ind,answers) in zip(INDICES, zip(*c))), 
    key=lambda x: x[1])

我知道这个答案介绍了一些列表理解和 lambda(和生成器),但是您要求一种清理它的方法,这是您可以使用的工具的一个示例。希望这可以为您提供所需的帮助!

注意:此答案未考虑平局。但我相信您可以从这里开始将这些示例集成到您的实际代码中

于 2012-11-25T03:28:55.237 回答