2016-11-01 3 views
0

파이썬 함수를 작성하여 숫자 목록을 숫자 목록으로 정렬하려고합니다. 각 목록에는 각 숫자의 인덱스가 포함 된 숫자 만 들어 있습니다. 큰 목록의 하위 목록정수 목록을 숫자 목록 합계 목록으로 정렬

따라서, 예를 들어, 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) 
관련 문제