2016-11-01 9 views
0

数字のリストを数字のリストにソートするPython関数を書こうとしていますが、各サブリストは、より大きいリストのサブリスト数字リストによるリストのリストへの整数リストの並べ替え

したがって、たとえば、1から25までの数字のすべてのために、それはこのようなリストのリストを生成する必要があります。

[[], [1, 10], [2, 11, 20], [3, 12, 21], [4, 13, 22], [5, 14, 23], [6, 15, 24], [7, 16], [8, 17], [9, 18], [19]] 

私がこれまでに次のコードを持っている:

def digit_sum(integer_data_type): 
    int_string = str(integer_data_type) 
    sum = 0 
    for digits in int_string: 
     sum += int(digits) 
    return sum 


def organize_by_digit_sum(integer_list): 
    integer_list.sort() 
    max_ds = 9*len(str(max(integer_list)))+1 
    list_of_lists = [] 
    current_ds = 0 
    while current_ds <= max_ds: 
      current_list = [] 
      for n in integer_list: 
        if digit_sum(n) == current_ds: 
          current_list.append(n) 
      list_of_lists.append(current_list) 
      current_ds += 1 
    return list_of_lists 

明らかに、これは0から最大桁の合計までの各桁の合計に対して、整数リスト全体を繰り返しループする必要があるため、非効率的です。

また、最初に、最大桁合計が最大整数の9倍であると仮定します。明らかにするには、可能なdigit_sumのサブリストを常に持っていて、特定の桁の合計のサブリストをリストのリストのインデックスで参照できるようにする必要があります。

私は関数がリスト内の各整数を一回だけループし、正しいサブリストに追加する必要があります。

これについての助力や洞察をいただければ幸いです。

答えて

2

itertoolsを使用しても構わない場合は、より効率的な方法があります。

from itertools import groupby 
digit_sum = lambda x: sum(int(i) for i in str(x)) 
[list(g) for _, g in groupby(sorted(range(1,26), key = digit_sum), key = digit_sum)] 
            # ^^^^^^^^^^ replace this with your actual data 
# [[1, 10], 
# [2, 11, 20], 
# [3, 12, 21], 
# [4, 13, 22], 
# [5, 14, 23], 
# [6, 15, 24], 
# [7, 16, 25], 
# [8, 17], 
# [9, 18], 
# [19]] 

それはここで動作する方法:あなたはあなたのリストには、桁の合計によってグループにgroupby()メソッドを使用できるように、整数の数字和によって、あなたの元のリストをソートするsorted()を使用して、グループをループして変換各グループの整数をリストに追加します。

更新: サブリストの数字和がインデックスに等しいリストを取得するには、まず辞書を作成することができます。

dict_ = dict((k,list(g)) for k, g in groupby(sorted(range(1,26), key = digit_sum), key = digit_sum)) 

dict_ 
# {1: [1, 10], 
# 2: [2, 11, 20], 
# 3: [3, 12, 21], 
# 4: [4, 13, 22], 
# 5: [5, 14, 23], 
# 6: [6, 15, 24], 
# 7: [7, 16, 25], 
# 8: [8, 17], 
# 9: [9, 18], 
# 10: [19]} 

[dict_.get(key, []) for key in range(max(dict_.keys()))] 
# [[], 
# [1, 10], 
# [2, 11, 20], 
# [3, 12, 21], 
# [4, 13, 22], 
# [5, 14, 23], 
# [6, 15, 24], 
# [7, 16, 25], 
# [8, 17], 
# [9, 18]] 
+0

はアスカーが探しているまさにこのですか?私はこれがインナーリストをその桁の和と等しいインデックスに置くとは思わない。代わりに、単に集計して桁でソートします。 – beeftendon

0

あなたは空のリストを離れたソリューションをしたい場合は、あなたのデータは、はるかに希薄であると仮定し、そう

>>> def digit_sum(digits): 
... total = 0 
... while digits != 0: 
...  total += digits % 10 
...  digits = digits // 10 
... return total 
... 
>>> numbers = list(range(1,26)) 
>>> pairs = sorted((digit_sum(n),n) for n in numbers) 
>>> pairs 
[(1, 1), (1, 10), (2, 2), (2, 11), (2, 20), (3, 3), (3, 12), (3, 21), (4, 4), (4, 13), (4, 22), (5, 5), (5, 14), (5, 23), (6, 6), (6, 15), (6, 24), (7, 7), (7, 16), (7, 25), (8, 8), (8, 17), (9, 9), (9, 18), (10, 19)] 
>>> maximum_sum = pairs[-1][0] 
>>> list_of_lists = [[] for _ in range(maximum_sum+1)] 
>>> for pair in pairs: 
... list_of_lists[pair[0]].append(pair[1]) 
... 
>>> list_of_lists 
[[], [1, 10], [2, 11, 20], [3, 12, 21], [4, 13, 22], [5, 14, 23], [6, 15, 24], [7, 16, 25], [8, 17], [9, 18], [19]] 
>>> 

とスペース効率があなたの主な関心事ではないですが、私はタプルのリストを使用します
>>> numbers = [4,25,47,89] 
>>> pairs = sorted((digit_sum(n),n) for n in numbers) 
>>> pairs 
[(4, 4), (7, 25), (11, 47), (17, 89)] 
>>> maximum_sum = pairs[-1][0] 
>>> list_of_lists = [[] for _ in range(maximum_sum+1)] 
>>> for pair in pairs: 
... list_of_lists[pair[0]].append(pair[1]) 
... 
>>> from pprint import pprint 
>>> pprint(list_of_lists,width=2) 
[[], 
[], 
[], 
[], 
[4], 
[], 
[], 
[25], 
[], 
[], 
[], 
[47], 
[], 
[], 
[], 
[], 
[], 
[89]] 
>>> 

そして、あなたのようなあなたのデータにアクセスすることができます

>>> list_of_lists[17] 
[89] 
>>> list_of_lists[8] 
[] 
>>> 
2

正確に一度データ上で次のループとキー和があり、値はその合計に相当アイテムである辞書を返します。

from collections import defaultdict 
from pprint import pprint 

def group_by_sum(lst): 
    d = defaultdict(list) 
    for i in lst: 
     d[sum(int(j) for j in str(i))].append(i) 
    return d 

pprint(group_by_sum(range(1, 25))) 
# {1: [1, 10], 
# 2: [2, 11, 20], 
# 3: [3, 12, 21], 
# 4: [4, 13, 22], 
# 5: [5, 14, 23], 
# 6: [6, 15, 24], 
# 7: [7, 16], 
# 8: [8, 17], 
# 9: [9, 18], 
# 10: [19]} 

あなたは、リストを持っている総和に基づいて、辞書の値を並べ替えることができますが、私は辞書として、あなたのデータを維持することはより良いサービスを提供かもしれないと思います。

+0

何らかの理由で出力が厳密にリストである必要がない限り、これは良いことです。空リストの束を持たずに効果的に同じことを実現します。 – beeftendon

0

非常に簡単:

list_of_lists = [[] for i in range(11)] 

for i in range(25): 
    digit_sum = sum(int(i) for i in str(i)) 
    list_of_lists[digit_sum].append(i) 

print (list_of_lists) 
関連する問題