2013-06-08 3 views
0

Дано множество или список (предположим, что его заказал)Группировка список целых чисел в диапазоне на куски

myset = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 

Я хочу, чтобы узнать, сколько цифры в диапазоне. сказать, что мой диапазон 10. Затем дается список выше, у меня есть два комплекта 10.

Я хочу, чтобы функция возврата [10,10]

если мой диапазон был 15. Тогда я должен получить [15,5]

Диапазон изменится. Вот что я придумал

myRange = 10 
start = 1 
current = start 
next = current + myRange 
count = 0 
setTotal = [] 
for i in myset: 
    if i >= current and i < next : 
     count = count + 1 
     print str(i)+" in "+str(len(setTotal)+1) 
    else: 
     current = current + myRange 
     next = myRange + current 
     if next >= myset[-1]: 
      next = myset[-1] 
     setTotal.append(count) 
     count = 0 

print setTotal 

Выход

1 in 1 
2 in 1 
3 in 1 
4 in 1 
5 in 1 
6 in 1 
7 in 1 
8 in 1 
9 in 1 
10 in 1 
12 in 2 
13 in 2 
14 in 2 
15 in 2 
16 in 2 
17 in 2 
18 in 2 
19 in 2 
[10, 8] 

уведомления 11 и 20, где пропущена. Я также играл с условием и получил проводные результаты.

EDIT: Диапазон определяет диапазон, в котором каждое значение в диапазоне должно учитываться в один патрон.

подумайте о диапазоне от текущего значения до currentvalue + range как один кусок.

EDIT:

Wanted выход:

1 in 1 
2 in 1 
3 in 1 
4 in 1 
5 in 1 
6 in 1 
7 in 1 
8 in 1 
9 in 1 
10 in 1 
11 in 2 
12 in 2 
13 in 2 
14 in 2 
15 in 2 
16 in 2 
17 in 2 
18 in 2 
19 in 2 
[10, 10] 
+1

Можете ли вы уточнить, что такое «диапазон» есть? – Blender

+1

Не могли бы вы объяснить логику «диапазона» лучше? – karthikr

+0

Я пробовал. В приведенном выше правиле. – Cripto

ответ

2

С помощью функции правого ключа, метод groupby в itertools модуль делает делает это довольно просто:

from itertools import groupby 

def ranger(values, range_size): 
    def keyfunc(n): 
     key = n/(range_size+1) + 1 
     print '{} in {}'.format(n, key) 
     return key 

    return [len(list(g)) for k, g in groupby(values, key=keyfunc)] 

myset = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 
print ranger(myset, 10) 
print ranger(myset, 15) 
-1

Если вы не заботитесь о том, что цифры в данном фрагменте, вы можете рассчитать размер легко:

def chunk_sizes(lst, size): 
    complete = len(lst) // size # Number of `size`-sized chunks 
    partial = len(lst) % size # Last chunk 

    if partial: # Sometimes the last chunk is empty 
     return [size] * complete + [partial] 
    else: 
     return [size] * complete 
+0

какой размер, я не заботясь о размере. Я хочу, чтобы числа между (n, m) были разделены на патрон, где n - моя нижняя граница, а m - верхняя граница. – Cripto

+0

@ user1048138: прочитайте код, прежде чем говорить, что он не работает. – Blender

+0

Не могли бы вы объяснить код. Я не понимаю, но это работает. – Cripto

1

Вы хотите использовать простое разделение и остаток; divmod() function дает вам обоим:

def chunks(lst, size): 
    count, remainder = divmod(len(lst), size) 
    return [size] * count + ([remainder] if remainder else []) 

Чтобы создать желаемый результат, а затем использовать выход chunks():

lst = range(1, 21) 
size = 10 

start = 0 
for count, chunk in enumerate(chunks(lst, size), 1): 
    for i in lst[start:start + chunk]: 
     print '{} in {}'.format(i, count) 
    start += chunk 

count является номер текущего фрагмента (начиная с 1, питон использует 0- основанный на индексировании).

Это печатает:

1 in 1 
2 in 1 
3 in 1 
4 in 1 
5 in 1 
6 in 1 
7 in 1 
8 in 1 
9 in 1 
10 in 1 
11 in 2 
12 in 2 
13 in 2 
14 in 2 
15 in 2 
16 in 2 
17 in 2 
18 in 2 
19 in 2 
20 in 2 
Смежные вопросы