Разделение длинного кортежа на меньшие - PullRequest
11 голосов
/ 16 октября 2010

У меня длинный кортеж типа

(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 списков.Мой друг сказал, что я должен разделить его, но я просто не могу его получить.*

Ответы [ 4 ]

9 голосов
/ 16 октября 2010

Ну, для этого есть определенная идиома:

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)

Но это сложно объяснить.Несколько более общая версия этого приведена в рецептах itertools .

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

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)]

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

2 голосов
/ 16 октября 2010
>>> 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 голосов
/ 16 октября 2010

Некоторое время назад я написал такую ​​функцию, как gist, доступную по адресу 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 голосов
/ 16 октября 2010

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

 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))
...