2012-11-24 52 views
0
CONSTANTS: 

NDP_INDEX = 0 
GREEN_INDEX = 1 
LIBERAL_INDEX = 2 
CPC_INDEX = 3 

每個方的數據出現在4元素列表中的索引dist。如何在不使用一堆if語句的情況下縮短此代碼

PARTY_INDICES = [NDP_INDEX, GREEN_INDEX, LIBERAL_INDEX, CPC_INDEX] 

一個字典,其中每個鍵是一個派對名稱,每個值是該派對的索引。

NAME_TO_INDEX = {'NDP': NDP_INDEX, 
'GREEN': GREEN_INDEX,'LIBERAL': LIBERAL_INDEX,'CPC': CPC_INDEX} 

一個字典,其中每個鍵是一方的索引,每個值是該方的名稱。

INDEX_TO_NAME = {NDP_INDEX: 'NDP',GREEN_INDEX: 'GREEN', LIBERAL_INDEX: 
'LIBERAL',CPC_INDEX: 'CPC'} 


def voting_range(range_votes): 
    ''' 
(list of list of int) -> tuple of (str, list of int) 
#range_votes is a list of integers of range ballots for a single 
#riding; the order of the inner list elements corresponds to the order 
#of the parties in PARTY_INDICES.Based on range_votes, return a tuple 
#where the first element is the name of the party winning the seat and 
#the second is a list with the total range_votes for each party in the 
#order specified in PARTY_INDICES. 

>>> voting_range([[5, 4, 1, 4], [3, 2, 2, 5], [3, 3, 1, 4,]]) 
('CPC', [11, 9, 4, 13]) 

''' 

NDP_count = 0 
GREEN_count = 0 
LIBERAL_count = 0 

for sub_list in range_votes: 
    NDP_count += sub_list[0] 
    GREEN_count += sub_list[1] 
    LIBERAL_count += sub_list[2] 
    CPC_count += sub_list[3] 

PARTY_INDICES[0] = NDP_count 
PARTY_INDICES[1] = GREEN_count 
PARTY_INDICES[2] = LIBERAL_count 
PARTY_INDICES[3] = CPC_count 

winner = max(NDP_count, GREEN_count, LIBERAL_count, CPC_count) 
if winner == NDP_count: 
    return 'NDP', PARTY_INDICES 
elif winner == GREEN_count: 
    return 'GREEN', PARTY_INDICES 
elif winner == LIBERAL_count: 
    return 'LIBERAL', PARTY_INDICES 
elif winner == CPC_count: 
    return 'CPC', PARTY_INDICES 

我不知道如何縮短這甚至利用輔助功能,因爲我們不允許創建新的常數(通用變量),但只是局部變量

回答

2

試試這個:

for sub_list in range_votes: 
    for i in range(4): 
     PARTY_INDICES[i] += sub_list[i] 
return ({PARTY_INDICES[0] : 'NDP', PARTY_INDICES[1] : 'GREEN', ...}[max(PARTY_INDICES)], 
     PARTY_INDICES) 

這就像我願意做到的一樣短;-)

+0

您可以在範圍(4)中爲我做第二個:PARTY_INDICES [i] + = sub_list [0]以替換​​分配。 ;-) – GaretJax

+0

@GaretJax,的確如此:) – StoryTeller

1

你不需要所有的這些字典和範圍變量,並定義/枚舉的東西。這是一個少一點C和多一點蟒蛇:

votes=[[5, 4, 1, 4], [3, 2, 2, 5], [3, 3, 1, 4,]] 
parties=['NDP','GREEN','LIBERAL','CPC'] 

def voting_range(v): 
    totals = [sum(x) for x in zip(*v)] # transpose row/col of list of lists 
    pname = parties[totals.index(max(totals))] 
    return (pname,totals) 

>>> voting_range(votes) 
('CPC',[11, 9, 4, 13]) 

有一些神奇的python事情在這裏進行。 *v解開列表的列表,並將它們作爲單獨的參數提供給zip,後者返回一個迭代,它給出列表中每個參數的第一個元素,然後是列表中每個參數的第二個元素,依此類推。這具有轉置矩陣的效果(交換行和列)。在這種形式下,簡單地總結每個清單將是投票總數。包裝在括號中的for x in語法是list comprehension,另一個令人敬畏的python特性,它可以有效地從iterables創建列表。最後,index是一個list method,它將返回具有指定值的第一個元素的索引,在本例中爲最大值。由於v的元素長度應與參與方數量相同,因此這也將成爲參與方列表的索引。

+0

如果不允許增加(或在這種情況下減少)派對定義,或者從現有定義構建它,那麼也可以在派生函數內部移動派對定義。 – engineerC