2010-03-15 41 views
19

Tôi muốn viết một hàm khôi phục danh sách [1,5,3,6,...] và cung cấp [1,1,5,5,3,3,6,6,...] bất kỳ ý tưởng nào về cách thực hiện? nhờsao chép từng thành viên trong một danh sách - python

+2

Âm thanh làm bài tập. Có nhiều cách tốt hơn để làm việc với một danh sách hơn là nhân đôi các phần tử. –

Trả lời

12
>>> a = [1, 2, 3] 
>>> b = [] 
>>> for i in a: 
    b.extend([i, i]) 


>>> b 
[1, 1, 2, 2, 3, 3] 

hoặc

>>> [a[i//2] for i in range(len(a)*2)] 
[1, 1, 2, 2, 3, 3] 
+0

Bạn cũng nên sử dụng '//' để chia tầng trong Python 2. –

+0

@Mike: chắc chắn bạn đúng, ngoại trừ khóa học trong phân chia '/' đảm bảo rằng 'int' được trả về. – SilentGhost

38
>>> a = range(10) 
>>> [val for val in a for _ in (0, 1)] 
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9] 

N.B. _ theo truyền thống được sử dụng như một tên biến giữ chỗ mà bạn không muốn làm bất cứ điều gì với nội dung của biến. Trong trường hợp này, nó chỉ được sử dụng để tạo ra hai giá trị cho mỗi lần vòng vòng ngoài.

Để biến điều này từ danh sách thành máy phát, hãy thay thế các dấu ngoặc vuông bằng dấu ngoặc tròn.

+1

'_' là, những ngày này, được sử dụng cho i18n/l10n (google). Tôi vẫn có xu hướng sử dụng nó * nếu * Tôi biết sẽ không có một i18n trong mô-đun này. Khác tôi (sẽ) sử dụng '__' (hai dấu gạch dưới). –

1

Tôi sẽ sử dụng

import itertools 
foo = [1, 5, 3, 6] 
new = itertools.chain.from_iterable([item, item] for item in foo) 

new sẽ là một iterator mà uể oải lặp trên các mặt hàng nhân đôi. Nếu bạn cần danh sách thực tế được tính, bạn có thể làm list(new) hoặc sử dụng một trong các giải pháp khác.

+1

hoặc ngắn hơn: 'itertools.chain.from_iterable (itertools.izip (foo, foo))' –

+0

Tôi coi mã đó ngắn hơn nhưng dường như không rõ ràng hơn với tôi. –

6

Nếu bạn đã có roundrobin thức được mô tả trong tài liệu hướng dẫn cho itertools -Và nó là khá tiện dụng-sau đó bạn chỉ có thể sử dụng

roundrobin(my_list, my_list) 
+0

+1, đây là một cách hay để thực hiện việc này. –

1

Đối với càng nhiều càng Guido không thích các nhà khai thác chức năng, họ có thể được khá darned handy:

>>> from operator import add 
>>> a = range(10) 
>>> b = reduce(add, [(x,x) for x in a]) 
+0

Trong trường hợp giảm, tiện dụng thường có nghĩa là đáng kinh ngạc chậm. Điều quan trọng là phải đo lường những gì 'giảm' đang làm. Thông thường, nó gây sốc bao nhiêu tính toán giảm lực lượng. –

+0

Tôi đã thực hiện một kịch bản thử nghiệm với mỗi một trong các phương pháp trên trang này với các baselist = range (10) và 1.000.000 iterations. Tốc độ chậm nhất mất 5.094 giây và nhanh nhất mất 3.622 giây. Ví dụ giảm của tôi mất 3.906 giây. –

+1

'phạm vi (10)' là nhỏ, vì vậy sự phức tạp trả một vai trò nhỏ. Giải pháp này là bậc hai; tất cả những người khác tôi thấy ở đây là tuyến tính. Ngoài ra, một số người khác dường như dễ đọc hơn đối với tôi. –

8

Tôi sẽ sử dụng zipitertools.chain.

>>> import itertools 
>>> l = [1,5,3,6,16] 
>>> list(itertools.chain(*zip(l,l))) 
[1, 1, 5, 5, 3, 3, 6, 6, 16, 16] 

Lưu ý: Tôi chỉ sử dụng list để sử dụng máy phát điện để phù hợp để in. Có thể bạn không cần cuộc gọi list trong mã của mình ...

1

Có thể sử dụng phép nhân danh sách. Trường hợp bạn cần mỗi thành viên danh sách với nhau chỉ cần sử dụng phương pháp được sắp xếp.

>>> lst = [1,2,3,4] 
>>> sorted(lst*2) 
[1,1,2,2,3,3,4,4] 
+0

Còn nếu bạn muốn giữ lại thứ tự của danh sách gốc? Điều gì sẽ xảy ra nếu các mục trong danh sách không thể đặt hàng? – Moberg

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