2010-10-16 25 views
9

Tôi có một tuple dài nhưspliting một tuple dài vào tuples nhỏ

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

và tôi đang cố gắng để tách nó thành một tuple của các bộ như

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

Tôi mới vào python và tôi không tốt lắm với các bộ t (2, 2, 10, 10, 344, 344, 45, 43, 2, 2, 10, 10, 12, 8, 2, 10). Người bạn của tôi nói tôi nên chia nó nhưng tôi không thể lấy nó -_-

Tôi cần chia bộ dữ liệu thành 4 thành phần mà sau này tôi sẽ sử dụng một hình chữ nhật để vẽ hình ảnh với PIL.

+1

Sẽ tốt nếu bạn giải thích những gì bạn đang làm với bộ dữ liệu yêu cầu chia nhỏ. Bạn có thể sẽ nhận được nhiều câu trả lời hữu ích và mang tính thông tin hơn theo cách đó. – JoshD

+5

@ John: FWIW, tôi không nghĩ rằng điều này là phức tạp hoặc không bình thường đủ để nó cần rất nhiều bối cảnh. –

Trả lời

9

Vâng có một thành ngữ nhất định cho rằng:

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) 

Nhưng loại hình này của phức tạp để giải thích. Phiên bản chung chung hơn một chút về điều này được liệt kê trong the itertools receipes.

Bạn cũng có thể cắt các tuple mình

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

mà có lẽ những gì bạn bè của bạn có nghĩa là.

+4

Tôi sẽ không gọi đó là thành ngữ - tôi chưa bao giờ thấy nó trước đây, và tôi mất vài giây để tìm ra những gì đang diễn ra. Không có gì sai với điều này, nhưng tất nhiên, hãy chắc chắn để tài liệu và doctest. –

+0

Cảm ơn nó đã làm việc: D – giodamelio

+0

Nhân tiện, tôi khuyên bạn nên 'return itertools.izip (* args)', do đó, nó hoạt động đúng với các trình vòng lặp lớn bằng cách không cố gắng tiêu thụ toàn bộ vòng lặp. Một đầu vào thử nghiệm tốt là 'itertools.cycle ((1,2,3))'. –

0

Một câu trả lời có thể (sử dụng một máy phát điện):

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

Giống như @ ghostdog74 câu trả lời bởi vì, ngay cả khi tuple cuối cùng có 1 phần tử trong đó, nó trở thành tuple cuối cùng với 1 phần tử, các giải pháp khác chỉ đơn giản là để lại tuple cuối cùng của 1 phần tử. – NullException

0

tôi đã viết một hàm như ý chính một số thời gian trở lại, có sẵn tại 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)] 

Mã này dài hơn các giải pháp được đưa ra ở trên, nhưng bao gồm tất cả các điều kiện phân chia chuỗi có thể có.

+0

Cảm ơn nhưng một ở trên chỉ hoạt động tốt. tiết kiệm mã vì nó có thể rất sử dụng đầy đủ ở đúng nơi. – giodamelio

Các vấn đề liên quan