2011-08-18 55 views
5

Vì vậy, tôi có một loạt các hình thức sau đây:Tại sao tôi không thể nhận được hai danh sách từ một danh sách hiểu?

[(1, u'first_type', u'data_gid_1'), 
(2, u'first_type', u'data_gid_2'), 
(3, u'first_type', u'data_gid_3'), 
(4, u'first_type', u'data_gid_4')] 

Bây giờ tôi muốn trích xuất đầu tiên và yếu tố cuối cùng của mỗi danh sách bên vào danh sách riêng biệt. Vì vậy, nếu tôi làm:

>>> ids = [dat[0] for dat in all_data] 
>>> gds = [dat[2] for dat in all_data] 

Điều này hoạt động như tôi mong đợi. Tuy nhiên tôi đã cố gắng để kết hợp hai thành một cuộc gọi, một cái gì đó như:

(ids, gds) = [(dat[0], dat[2]) for dat in all_data] 

này tuy nhiên không thành công với một: ValueError: too many values to unpack

Vì vậy, bất cứ ai có thể giải thích lý do tại sao điều này xảy ra và nếu những gì tôi đang cố gắng làm thậm chí có thể.

Kính trọng, Bogdan

+1

Có điều gì sai trái khi bỏ hai dòng không? Tôi có nghĩa là đôi khi nó chỉ là tốt đẹp để được rõ ràng. –

+1

Không có gì sai, đó vẫn là giải pháp tôi đang sử dụng, tôi chỉ muốn hiểu tại sao tôi lại gặp lỗi khi sử dụng trong tương lai. – Bogdan

+0

@Bogdan Điều đó thực sự đáng kính. Tôi sẽ cung cấp cho bạn một +1 cho nhận xét đó. – cwallenpoole

Trả lời

8

Nó không làm việc vì chiều dài của [(dat[0], dat[2]) for dat in all_data] là giống như chiều dài của all_data, mà không phải là chiều dài tương tự như các tuple (ids, gds).

Hãy thử điều này thay vì:

(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data]) 

hoặc thậm chí ngắn hơn:

(ids, gds) = zip(*all_data)[::2] 

Như đã đề cập trong câu trả lời khác, idsgds bây giờ sẽ được các bộ, vì vậy nếu bạn cần danh sách, làm như thế này:

(ids, gds) = map(list, zip(*all_data)[::2]) 



zip(*something) là một thành ngữ khá thường xuyên xảy ra trong python. Nếu bạn nhìn vào một danh sách liệt kê như một ma trận, tức là

l = [[1, 2, 3], 
    [4, 5, 6]] 

Sau đó zip(*l) transposes rằng ma trận:

zip(*l) == [(1, 4), 
      (2, 5), 
      (3, 6)] 

Các * công trình như thế này: some_func(*some_list)giải nénsome_list để các chức năng là trong hiệu ứng được gọi với các phần tử của some_list làm đối số. Vì vậy, zip(*l) cũng giống như zip([1, 2, 3], [4, 5, 6]). Here's phần liên quan của hướng dẫn python.

zip hành vi giống như một zipper, vì thế mà tên, vì vậy nó sẽ trả về một danh sách với các yếu tố: một tuple của tất cả các yếu tố đầu tiên của các đối số được đưa ra, theo sau là một tuple của tất cả các yếu tố thứ hai, vv

+1

Rất đẹp. Mặc dù một lời giải thích tốt hơn một chút để giúp OP: "Quá nhiều giá trị để giải nén" xảy ra vì bạn đang cố gán một danh sách 4 phần tử cho một bộ phần tử 2 phần tử. " +1. –

+0

Cảm ơn các đầu vào. Nhận ngay bây giờ. – Bogdan

+0

Có nghĩa là hỏi chính xác cái zip đó là gì(). Cảm ơn bạn đã làm rõ. Sẽ chấp nhận ngay sau khi thời gian hết hạn. – Bogdan

1

[(dat[0], dat[2]) for dat in all_data] có nghĩa là bạn đang tạo danh sách các bộ dữ liệu (dat[0],dat[2]). Điều đó không có nghĩa là bạn có hai danh sách, một trong số d[0] và một danh sách khác là d[2].

Bạn chỉ cần sử dụng zip, nhưng điều đó sẽ dẫn đến các bộ dữ liệu.Nếu bạn muốn danh sách, bạn sẽ phải áp dụng list đến kết quả:

(ids, gds) = map(list,zip(*[(dat[0], dat[2]) for dat in a])) 
4

Mã dưới đây cũng sẽ làm các việc lừa:

data = [(1, u'first_type', u'data_gid_1'), 
(2, u'first_type', u'data_gid_2'), 
(3, u'first_type', u'data_gid_3'), 
(4, u'first_type', u'data_gid_4')] 

ids, gds = ([row[i] for row in data] for i in [0,2]) 
0

Vì bạn đang tạo ra hai danh sách riêng, hãy thử này:

ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data] 

hoặc bạn có thể giải nén nó vào một danh sách duy nhất với lệnh bạn sử dụng:

x = [(dat[0], dat[2]) for dat in all_data] 
Các vấn đề liên quan