如何为列表的每个索引给出分数

时间:2012-11-24 15:07:03

标签: python-3.x

def voting_borda(rank_ballots):
    '''(list of list of str) -> tuple of (str, list of int)

该参数是一个4元素列表的列表,代表单次骑行的等级选票。

Borda Count是根据排名分配点来确定的。每个第一选择排名获得3分,每个第二选择排名获得2分,每个第三选择排名获得1分。 (因排名第四而没有得分。)例如,上面显示的排名选票将为自由党统计贡献3分,绿色统计分2分,CPC分数1分。得分最高的一方赢得了席位。

根据Borda Count返回一个元组,其中第一个元素是获胜方的名称,第二个元素是包含每个方的总点数的四元素列表。列表元素的顺序对应于PARTY_INDICES中各方的顺序。

#>>> voting_borda([['GREEN','NDP', 'LIBERAL', 'CPC'], ['GREEN','CPC','LIBERAL','NDP'],
    ['LIBERAL','NDP', 'CPC', 'GREEN']])
#('GREEN',[4, 6, 5, 3])

list_of_party_order = []
for sublist in rank_ballots:
    for party in sublist[0]:
        if party == 'GREEN':
            GREEN_COUNT += 3
        elif party == 'NDP':
            NDP_COUNT += 3
        elif party == 'LIBERAL':
            LIBERAL_COUNT += 3
        elif party == 'CPC':
            CPC_COUNT += 3

    for party in sublist[1]:
        if party == 'GREEN':
            GREEN_COUNT += 2
        elif party == 'NDP':
            NDP_COUNT += 2
        elif party == 'LIBERAL':
            LIBERAL_COUNT += 2
        elif party == 'CPC':
            CPC_COUNT += 2

   for party in sublist[2]:
        if party == 'GREEN':
            GREEN_COUNT += 1
        elif party == 'NDP':
            NDP_COUNT += 1
        elif party == 'LIBERAL':
            LIBERAL_COUNT += 1
        elif party == 'CPC':
            CPC_COUNT += 1

我不知道如何为列表的每个索引提供积分更简单。 有人可以帮帮我吗?没有太复杂。谢谢!

2 个答案:

答案 0 :(得分:0)

这不是完全您要求的内容,它会返回一个包含两个值的元组:赢家的名字,以及所有各方及其值的字典,而不是只有值的列表在我看来,这对几乎任何情况都更好,如果你不喜欢它,你可以把它转换成一个列表。

它也需要多个参数而不是一个列表,但您可以通过从*

中删除*args来更改它

但是,请注意,如果您关心速度而不是小代码,那么这不是最好的方法。它确实有用,但是。

以这种方式优于您的代码,允许您不使用功能中的任何一方名称或当事人数量,这样就可以添加,重命名或删除各方。

def voting_borda(*args):
    results = {}
    for sublist in args:
        for i in range(0, 3):
            if sublist[i] in results:
                results[sublist[i]] += 3-i
            else:
                results[sublist[i]] = 3-i

    winner = max(results, key=results.get)
    return winner, results

print(voting_borda(
    ['GREEN','NDP', 'LIBERAL', 'CPC'],
    ['GREEN','CPC','LIBERAL','NDP'],
    ['LIBERAL','NDP', 'CPC', 'GREEN']
))

将导致:('GREEN', {'LIBERAL': 5, 'NDP': 4, 'GREEN': 6, 'CPC': 3})

答案 1 :(得分:0)

我找到了你的投票模拟作业online,并在这里添加了一些常量,以简化解决问题的代码(尽管在开头可能看起来不像它们的定义)。

返回的元组的第一个元素不是完全所请求的格式 - 它是一个列表而不是单个值 - 来处理非常真实的平局投票的可能性,如图所示以下用于rank_ballots的示例数据值。即使没有平局,元素返回也是一个单例列表 - 实际上通常更容易处理,而不是根据不止一个而不同。

PARTY_NAMES = ['NDP', 'GREEN', 'LIBERAL', 'CPC']
NAME_TO_INDEX = {party:PARTY_NAMES.index(party) for party in PARTY_NAMES}
INDEX_TO_NAME = {PARTY_NAMES.index(party):party for party in PARTY_NAMES}

def voting_borda(rank_ballots):
    results = [0 for _ in PARTY_NAMES]
    MAX_POINTS = len(PARTY_NAMES)-1
    for ballot in rank_ballots:
        for i,party in enumerate(ballot):
            results[NAME_TO_INDEX[party]] += MAX_POINTS-i

    highest_rank = max(results)
    winners = [INDEX_TO_NAME[i] for i,total in enumerate(results) if total == highest_rank]
    return winners, results

rank_ballots = [['GREEN','NDP', 'LIBERAL', 'CPC'],
                ['GREEN','CPC','LIBERAL','NDP'],
                ['LIBERAL', 'GREEN', 'NDP', 'CPC'],
                ['LIBERAL','NDP', 'CPC', 'GREEN'],]

print(voting_borda(rank_ballots))

输出:

(['GREEN', 'LIBERAL'], [5, 8, 8, 3])