2010-10-16 4 views
9

У меня есть длинный кортеж, какSpliting длинного кортежа на более мелкие кортежи

(2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10) 

и я пытаюсь разбить его на кортеж кортежей как

((2, 2, 10, 10), (344, 344, 45, 43), (2, 2, 10, 10), (12, 8, 2, 10)) 

Я новичок в Python и я не очень хорошо с кортежами o (2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10) r. Мой друг сказал, что я должен расколоть его, но я просто не могу его получить. -_-

Мне нужно разбить кортеж на кортежи с четырьмя элементами, которые позже я буду использовать прямоугольники для рисования с помощью PIL.

+1

Было бы хорошо, если бы вы объяснили, что вы делаете с кортежем, который требует его разделения. Вероятно, вы получите более полезные и информативные ответы. – JoshD

+5

@JohnD: FWIW, я не думаю, что это сложно или достаточно необычно, что для этого нужен большой контекст. –

ответ

9

Ну есть некая идиома, что:

def grouper(n, iterable): 
    args = [iter(iterable)] * n 
    return zip(*args) 

t = (2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10) 
print grouper(4, t) 

Но его вид сложно объяснить. Несколько более общая версия этого указана в the itertools receipes.

Вы также можете нарезать кортеж себя

parts = (t[0:4], t[4:8], t[8:12], t[12:16]) 

# or as a function 
def grouper2(n, lst): 
    return [t[i:i+n] for i in range(0, len(t), n)] 

, который, вероятно, что ваш друг имел в виду.

+4

Я бы не назвал это идиоматическим - я даже не видел его раньше, и мне потребовалось несколько секунд, чтобы выяснить, что происходит. В этом нет ничего плохого, но, конечно же, обязательно документируйте и доктрины. –

+0

Спасибо, сработало: D – giodamelio

+0

Кстати, я бы настоятельно рекомендовал 'return itertools.izip (* args)', поэтому это корректно работает с большими итераторами, не пытаясь использовать весь итератор. Хорошим тестовым вводом является 'itertools.cycle ((1,2,3))'. –

0

Другой возможный ответ (с использованием генератора):

oldTuple = (2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10) 
newTuple = tuple(oldTuple[x:x+4] for x in range(0, len(oldTuple), 4)) 
1
>>> atup 
(2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10) 
>>> [ atup[n:n+4] for n,i in enumerate(atup) if n%4==0 ] 
[(2, 2, 10, 10), (344, 344, 45, 43), (2, 2, 10, 10), (12, 8, 2, 10)] 
+0

Как @ ghostdog74 отвечает, потому что, даже если последний кортеж имеет 1 элемент в нем, он становится последним кортежем с 1 элементом, другие решения просто оставляют последний кортеж из 1 элемента. – NullException

0

Я написал такую ​​функцию, как сутью некоторое время назад, доступный в http://gist.github.com/616853

def split(input_list,num_fractions=None,subset_length=None): 
    '''                                 
    Given a list/tuple split original list based on either one of two parameters given but NOT both,         
    Returns generator                             
    num_fractions : Number of subsets original list has to be divided into, of same size to the extent possible.      
        In case equilength subsets can't be generated, all but the last subset            
        will have the same number of elements.                    
    subset_length : Split on every subset_length elements till the list is exhausted.             

    ''' 
    if not input_list: 
     yield input_list #For some reason I can't just return from here : return not allowed in generator expression     
    elif not bool(num_fractions)^bool(subset_length): #Will check for both the invalid cases, '0' and 'None'.. Oh Python :)   
     raise Exception("Only one of the params : num_fractions,subset_length to be provided") 
    else: 
     if num_fractions: #calcluate subset_length in this case                   
      subset_length = max(len(input_list)/num_fractions,1) 

     for start in xrange(0,len(input_list),subset_length): 
      yield input_list[start:start+subset_length] 



>> list(list_split.split((2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10),subset_length=4)) 
[(2, 2, 10, 10), (344, 344, 45, 43), (2, 2, 10, 10), (12, 8, 2, 10)] 

Код длиннее решения, приведенные выше, но охватывает все возможные условия расщепления последовательностей.

+0

Спасибо, но одно выше работает отлично. сохраняя код, поскольку он может быть очень полезен в нужном месте. – giodamelio

Смежные вопросы