2013-02-26 37 views
9

Vì vậy, tôi có x=[(12,), (1,), (3,)] (danh sách các bộ dữ liệu) và tôi muốn x=[12, 1, 3] (danh sách các số nguyên) theo cách tốt nhất có thể? Bạn có thể giúp đỡ không?Danh sách Python các bộ dữ liệu vào danh sách int

+3

Vui lòng chỉnh sửa câu hỏi của bạn để đưa nỗ lực vào giải pháp. Cảm ơn bạn. – bernie

+0

là các bộ dữ liệu của bạn luôn có cùng một biểu mẫu? '(n,)'? –

+1

Một thay thế 'zip (* x) [0]' hoặc 'tiếp theo (zip (* x))' trên Py3k – JBernardo

Trả lời

5
y = [i[0] for i in x] 

Điều này chỉ hoạt động cho một phần tử trên mỗi bộ.

Tuy nhiên, nếu bạn có nhiều yếu tố mỗi tuple, bạn có thể sử dụng danh sách hơi phức tạp hơn sự hiểu biết:

y = [i[j] for i in x for j in range(len(i))] 

tham khảo: List Comprehensions

+1

@pedro - Có, nó sẽ luôn có một phần tử. – NullException

+0

Đối với giải pháp thứ hai: Nếu bạn cần làm phẳng chuỗi trình tự bất kỳ, có một công thức trong các tài liệu ['itertools'] (http://docs.python.org/2/library/itertools.html#recipes) được gọi là' flatten'. Nó có thể có giá trị hiểu cả điều đó và hiểu danh sách. – abarnert

+1

Bạn không nên đảo ngược thứ tự của 'for's? – phant0m

2

Chỉ cần làm điều này:

x = [i[0] for i in x] 

Giải thích :

>>> x=[(12,), (1,), (3,)] 

>>> x 
[(12,), (1,), (3,)] 

>>> [i for i in x] 
[(12,), (1,), (3,)] 

>>> [i[0] for i in x] 
[12, 1, 3] 
1

Đây là cách hiệu quả nhất:

x = [i for i, in x] 

hoặc tương đương

x = [i for (i,) in x] 

Đây là chậm hơn một chút:

x = [i[0] for i in x] 
+0

Bạn có chắc chắn về sự khác biệt về hiệu quả? Trong một bài kiểm tra nhanh với một phần tử 1M' danh sách' trong 3.3.0, chúng mất 4.15ms và 4.14ms tương ứng - và có vẻ như hơn 4ms trong số đó là thời gian lặp lại danh sách và xây dựng một danh sách mới, vì vậy không có gì có thể sẽ nhanh hơn. Nếu bạn thay đổi x thành một genexp và thay thế hai listcomps bằng một genexp fed thành 'deque (genexp, maxlen = 0)', tôi nhận được 1.36us so với 1.32us. – abarnert

+0

Quan trọng hơn, bạn đang hình dung ra kịch bản nào về việc ai sẽ quan tâm đến hai yếu tố nào hiệu quả hơn? – abarnert

+1

Xu hướng hiệu quả này cho Python trên SO đến từ đâu? Đối với tôi, nó có vẻ như một mẹo để đạt được nhiều điểm hơn. – phant0m

0

bạn có thể sử dụng chức năng bản đồ ....

map(lambda y: y[0], x) 
+2

Nếu bạn định sử dụng 'map', bạn có thể sử dụng' itemgetter' thay vì 'lambda'. – abarnert

11

Bạn không nói những gì bạn có nghĩa là "tốt nhất", nhưng có lẽ bạn có nghĩa là "nhất pythonic" hoặc "dễ đọc nhất" hoặc một cái gì đó như thế.

Việc hiểu danh sách được đưa ra bởi F3AR3DLEGEND có lẽ là đơn giản nhất. Bất cứ ai biết cách đọc một danh sách hiểu sẽ ngay lập tức biết ý nghĩa của nó.

y = [i[0] for i in x] 

Tuy nhiên, thường bạn không thực sự cần danh sách, chỉ cần một thứ có thể được lặp lại một lần. Nếu bạn có một tỷ nguyên tố trong x, việc xây dựng một tỷ nguyên tố y chỉ để lặp qua một phần tử tại một thời điểm có thể là một ý tưởng tồi. Vì vậy, bạn có thể sử dụng biểu thức trình tạo:

y = (i[0] for i in x) 

Nếu bạn thích lập trình hàm, bạn có thể thích sử dụng map. Nhược điểm của map là bạn phải vượt qua nó một chức năng, không chỉ là một biểu hiện, có nghĩa là bạn có cần phải sử dụng một hàm lambda, hoặc itemgetter:

y = map(operator.itemgetter(0), x) 

Trong Python 3, đây là tương đương với các máy phát điện biểu hiện; nếu bạn muốn có một list, hãy chuyển nó đến list. Trong Python 2, nó trả về một list; nếu bạn muốn một trình lặp, hãy sử dụng itertools.imap thay vì map.

Nếu bạn muốn có một dung dịch làm phẳng chung hơn, bạn có thể tự viết một cái, nhưng nó luôn đáng giá itertools cho các giải pháp chung loại này, và thực tế là một công thức được gọi là flatten được sử dụng để "Flatten one level of làm tổ ".Vì vậy, sao chép và dán vào mã của bạn (hoặc pip install more-itertools) và bạn chỉ có thể làm điều này:

y = flatten(x) 

Nếu bạn nhìn vào cách flatten được thực hiện, và sau đó như thế nào chain.from_iterable được thực hiện, và sau đó như thế nào chain là thực hiện, bạn sẽ nhận thấy rằng bạn có thể viết cùng một điều về nội trang. Nhưng tại sao bận tâm, khi flatten sẽ dễ đọc hơn và rõ ràng hơn?

Cuối cùng, nếu bạn muốn giảm bớt phiên bản generic vào một danh sách hiểu lồng nhau (hoặc biểu hiện máy phát điện, tất nhiên):

y = [j for i in x for j in i] 

Tuy nhiên, comprehensions danh sách lồng nhau là rất dễ dàng để có được sai, cả bằng văn bản Và đọc. (Lưu ý rằng F3AR3DLEGEND, cùng một người đã đưa ra câu trả lời đơn giản nhất trước, cũng đưa ra một hiểu biết lồng nhau và hiểu sai. Nếu anh ta không thể kéo nó ra, bạn có chắc chắn muốn thử không?) Đối với trường hợp thực sự đơn giản, họ ' không quá tệ, nhưng vẫn còn, tôi nghĩ rằng flatten dễ đọc hơn nhiều.

+0

Vì vậy, ý kiến ​​của bạn về việc giải quyết mẫu la bàn là gì? –

+0

@PavelAnossov: Điều gì về nó? Khi bạn muốn giải nén một tuple thành các biến có tên riêng biệt, nó rõ ràng là chính xác điều đúng. Khi bạn có một bộ dữ liệu mà bạn chỉ muốn biến thành một giá trị duy nhất, nó có vẻ không rõ ràng, nhưng nó không thực sự phản đối. – abarnert

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