2013-01-11 20 views
3

因此,我正在處理未知長度的列表。我需要把這份清單分成四部分。根據百分比將列表分成四部分,即使列表不能被10整除。Python

第一部分=第一20中的列表的%

部分從20%至40%的列表的

部分從列表

部分的40%至80%3 = 2 =四個=從80%到100%的名單。

現在這個問題是,如果列表少於10個元素,我的列表中的一些將是空的。我的問題是如何避免這個問題。

這是劇本我現在有:

x = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"] 

twentyPercentOne = len(x) * 0.2 

twentyPercentTwo = len(x) * 0.4 

fourtyPercentThree = len(x) * 0.8 

i = 0 
j = 2 

m = [] 
while j < (twentyPercentOne + 1): 
    m.append(x[i:j]) 
    i = (i + 2) 
    j = (j + 2) 

h = [] 
while j < (twentyPercentTwo + 1): 
    h.append(x[i:j]) 
    i = (i + 2) 
    j = (j + 2) 

l = []   
while j < (fourtyPercentThree + 1): 
    l.append(x[i:j]) 
    i = (i + 2) 
    j = (j + 2) 

t = x[i:len(x)] 

輸出:

[['one', 'two']] 
[['three', 'four']] 
[['five', 'six'], ['seven', 'eight']] 
['nine', 'ten'] 

輸出如果列表少於10長度: X = [ 「一」,「二「,」三「,」四「,」五「,」六「,」七「]

[['one', 'two']] 
[] 
[['three', 'four'], ['five', 'six']] 
['seven'] 

有人知道如何做這個?我知道它更像是一個數學問題,而不是Python問題,但我不知道如何去做,並且一直在爲它工作好幾天。我將不勝感激任何幫助。

感謝

回答

6

這應該是正確的方式,爲任何規模的分割數(不只有四個),(只要他們加起來1):

def percentage_split(seq, percentages): 
    assert sum(percentages) == 1.0 
    prv = 0 
    size = len(seq) 
    cum_percentage = 0 
    for p in percentages: 
     cum_percentage += p 
     nxt = int(cum_percentage * size) 
     yield seq[prv:nxt] 
     prv = nxt 

(這是一個發電機的功能,你可以得到你的四分位名單如下:

list(percentage_split(x, [0.25]*4)) 

,如果你有NUMP Ÿ安裝它可以是一個有點更簡潔:

from numpy import cumsum 

def percentage_split(seq, percentages): 
    cdf = cumsum(percentages) 
    assert cdf[-1] == 1.0 
    stops = map(int, cdf * len(seq)) 
    return [seq[a:b] for a, b in zip([0]+stops, stops)] 

,如果你只是想在四個相等的四分...

numpy.split(seq, 4) 
+0

可悲的是我沒有安裝numpy。我不明白你的percentage_split函數。它不會返回任何東西,我不知道如何返回我應該返回來得到我需要的分裂... – Adilicious

+0

你應該安裝和學習numpy,這是非常有用的。第一個函數是一個生成器函數,如果你想做任何嚴肅的(或有趣的,簡單而高效的)Python編程,你也應該瞭解它們http://www.python.org/dev/peps/pep-0255/ http ://www.ibm.com/developerworks/library/l-pycon/index.html – fortran

+0

我很想做到這一點(並可能在家裏做某些事情),但我在使用python的系統上這樣做2。7,不能以任何方式改變:( – Adilicious

0

應該清楚你,那是不可能的劃分一個列表以這種方式匹配長度。但這是另一種方式:

def do_split(x, percent): 
    L = len(x) 
    idx1 = [0] + list(int(L * p) for p in percent[:-1]) 
    idx2 = idx1[1:] + [L] 
    return list(x[i1:i2] for i1,i2 in zip(idx1, idx2)) 

splits = [0.2, 0.4, 0.8, 1.0] 
print do_split(["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"], splits) 
# ---> [['one', 'two'], ['three', 'four'], ['five', 'six', 'seven', 'eight'], ['nine', 'ten']] 
print do_split(["one", "two", "three", "four", "five", "six", "seven"], splits) 
# --> [['one'], ['two'], ['three', 'four', 'five'], ['six', 'seven']]