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

该参数是一个 4 元素列表的列表,代表单次选区的排名投票。

博尔达计数是通过根据排名分配积分来确定的。一方每获得第一名得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

我不知道如何更简单地为列表中的每个索引打分。有人可以帮帮我吗?不用太复杂。谢谢!

4

2 回答 2

0

这并不完全符合您的要求,它返回一个包含两个值的元组:获胜者的姓名,以及所有各方及其值的字典,而不是仅包含值的列表。在我看来,这几乎适用于任何情况,如果您不喜欢它,可以将其转换为列表。

它也需要多个参数而不是一个列表,但是您可以通过简单地删除*from*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})

于 2012-11-24T16:48:36.657 回答
0

我在网上找到了您的投票模拟作业,并在此处添加了一些常量,以简化解决问题的代码(尽管一开始的定义可能看起来不像)。

返回的元组的第一个元素并不完全符合请求的格式——它是一个列表而不是单个值——以处理相当真实的平局投票的可能性,如下面使用的示例数据值所示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])
于 2012-11-30T19:56:53.087 回答