2017-04-13 18 views
1

効率的に、数字をn個のグループに均等に分配する方法はありますか?Python - リストのリスト内の数字を均等に分割する

私はこの機能を考えましたが、この数字を完全に均等に分けるわけではありません。

def DivideList(total_num, div_num): 

    div = int(total_num)/int(div_num) 

    if (div_num < total_num): 
     div_list = [[div*i, div*(i+1)] for i in range(div_num)] 
     div_list[div_num-1][1] = total_num 
    else: 
     div_list = [[i, i+1] for i in range(total_num)] 

    return div_list 

print DivideList(100, 8) 

これもリストの理解で達成できますか?

EDIT:

例:

DivideList(20, 4) >> [[0, 5], [5, 10], [10, 15], [15, 20]]

DivideList(14, 4) >> [[0, 4], [4, 8], [8, 11], [11, 14]]

+0

ご希望の結果を投稿してください – Ajax1234

+0

また、あなたがnumpy.linspaceを使用して考えがありますが –

+2

を達成しようとしているもののサンプル例に言及してください?それはあなたが探しているものに類似したパラメータを使用して、通常の方法で数値を生成することができます。詳細はこちら: https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html – ma3oun

答えて

1

例1:

def DivideList(total_num, div_num): 
    div = total_num/div_num 
    left = total_num - div * div_num 
    result = [] 
    m = 0 
    for i in xrange(left): 
     k = m 
     m += (div + 1) 
     result.append([k, m]) 

    for i in xrange(div_num - left): 
     k = m 
     m += div 
     result.append([k, m]) 

    return result 

より簡潔:

def DivideList(total_num, div_num): 
    div = total_num/div_num 
    left = total_num - div * div_num 
    result = [] 
    for i in xrange(0, left*(div+1), div+1): 
     result.append([i, i+div+1]) 

    for i in xrange(left*(div+1), total_num, div): 
     result.append([i, i+div]) 

    return result 

例2: ここにあなたがしたいチャンクを生成するジェネレータです:

def DivideList(total_num, div_num): 
    div = total_num/div_num 
    left = total_num - div * div_num 
    m = 0 
    for i in xrange(left): 
     k = m 
     m += (div + 1) 
     yield [k, m] 

    for i in xrange(div_num - left): 
     k = m 
     m += div 
     yield [k, m] 

はもっと簡潔:

def DivideList(total_num, div_num): 
    div = total_num/div_num 
    left = total_num - div * div_num 
    for i in xrange(0, left*(div+1), div+1): 
     yield [i, i+div+1] 

    for i in xrange(left*(div+1), total_num, div): 
     yield [i, i+div] 
0

ここで結果を達成するための1つの可能性があります。十分でない場合は、処理したいコーナーケースを指定してください。たとえば、例のように、予想される引数がすでにintである場合は、intにキャストすることは意味がありません。

ma3ounによって示唆されるように、np.linspaceはこれを達成するための優れた方法です:

>>> def divide_list(total_num, div_num): 
...  temp = np.linspace(0, total_num, div_num + 1) 
...  return list(zip(temp[:-1], temp[1:])) 
... 
>>> divide_list(100, 8) 
[(0.0, 12.5), (12.5, 25.0), (25.0, 37.5), (37.5, 50.0), (50.0, 62.5), (62.5, 75.0), (75.0, 87.5), (87.5, 100.0)] 

これはあなたの最後の例とは異なり、でも手順を生成します。np.arangeを使用して

>>> divide_list(20, 4) 
[(0.0, 5.0), (5.0, 10.0), (10.0, 15.0), (15.0, 20.0)] 
>>> divide_list(14, 4) 
[(0.0, 3.5), (3.5, 7.0), (7.0, 10.5), (10.5, 14.0)] 

私の前の例:

>>> import numpy as np 
>>> def divide_list(total_num, div_num): 
...  div = total_num/div_num 
...  temp = np.arange(0, total_num + div, div) 
...  return list(zip(temp[:-1], temp[1:])) 
... 
>>> divide_list(100, 8) 
[(0.0, 12.5), (12.5, 25.0), (25.0, 37.5), (37.5, 50.0), (50.0, 62.5), (62.5, 75.0), (75.0, 87.5), (87.5, 100.0)] 
0

古いsugg estion:だから私はあなたの条件にまだ不明だが、私:あなたは、単にフロート部門を強制しようとしている場合

ので、

div = 1.0*total_num/div_num 

EDITようにコードを変更する 試行は以下の通りです。また、それはリスト内包でなければならないのでしょうか?この場合の可読性に実際に影響します。私はそれを2つのリスト内包表記で実装することができました。

def Segments(total_num,div_num): 
    return [(total_num/div_num)+1 if(i<total_num%div_num) else (total_num/div_num) for i in range(div_num)] 

def DivideList(series): 
    return [[sum(series[0:i]),sum(series[0:i+1])] for i in range(len(series))] 

print DivideList(Segments(100,8)) 

誰かがこれをさらに短縮/美化する可能性があります。

0

あなたがもっと考えると、それは数学の問題だと分かります。リストの理解の必要はありません。 を参照してください。

import math 
def DivideList(total_num, div_num): 
    num = math.ceil(total_num/div_num) 
    # result = [] 
    # for i in range(div_num - 1): 
    #  result.append([num*i,num*(1+i)]) 
    result = [[num*i,num*(i+1)] for i in range(div_num-1)] 
    result.append([(div_num-1)*num,total_num]) 
    return result 
関連する問題