2012-08-29 25 views
17

Đối với bây giờ tôi đã cố gắng để thực hiện dải() trên một danh sách các chuỗi và tôi đã làm điều này:Có cách nào tốt hơn để sử dụng dải() trên danh sách các chuỗi không? - python

i = 0 
for j in alist: 
    alist[i] = j.strip() 
    i+=1 

Có cách nào tốt hơn để làm điều đó?

+7

Upvoting cho downvote ẩn danh ngẫu nhiên ẩn danh. Nếu có điều gì đó sai trái với câu hỏi, thì hoàn toàn vô nghĩa nếu bạn không nói cho tác giả biết điều gì. – KRyan

+0

@DragoonWraith Nghe, nghe. – chucksmash

+3

Nếu bạn muốn lặp lại bằng cách sử dụng chỉ mục, hãy thực hiện 'for (i, value) trong liệt kê (alist)' – Kos

Trả lời

26

Có thể bạn không nên sử dụng tên list làm tên biến vì đó là một loại. Bất kể:

list = map(str.strip, list) 

này sẽ áp dụng các chức năng str.strip để mọi phần tử trong list, trả về một danh sách mới, và lưu trữ kết quả trở lại trong list.

+1

+1 đó là cách. Và nếu bạn muốn thay đổi cùng một thể hiện danh sách thay vì liên kết biến này với một biến mới (nói, không phá vỡ các tham chiếu khác vào danh sách này), hãy sử dụng cú pháp slice như @kojiro nói – Kos

+2

Ví dụ: 'map' là một lựa chọn. ('itertools.imap' có thể hoặc có thể không tốt hơn, tất nhiên, ví dụ như khi gán cho một slice). – Marcin

+0

@Kos Trong trường hợp đó, một giải pháp dựa trên trình vòng lặp sẽ còn tốt hơn (vì nó tránh tạo ra toàn bộ một danh sách mà sau đó không được xử lý và đang chờ thu gom rác). – Marcin

3

Tôi nghĩ bạn có nghĩa là

a_list = [s.strip() for s in a_list] 

Sử dụng một biểu thức máy phát điện có thể là một phương pháp tốt hơn, như thế này:

stripped_list = (s.strip() for s in a_list) 

cung cấp các lợi ích của việc đánh giá lười biếng, vì vậy strip chỉ chạy khi đưa yếu tố, bị tước bỏ, là cần thiết.

Nếu bạn cần tài liệu tham khảo vào danh sách vẫn còn nguyên vẹn nằm ngoài phạm vi hiện tại, bạn có thể muốn sử dụng cú pháp danh sách lát .:

a_list[:] = [s.strip() for s in a_list] 

Đối với bình luận quan tâm đến tốc độ của phương pháp tiếp cận khác nhau, có vẻ như nếu trong CPython cách tiếp cận phát-to-lát là hiệu quả nhất:

>>> from timeit import timeit as t 
>>> t("""a[:]=(s.strip() for s in a)""", """a=[" %d " % s for s in range(10)]""") 
4.35184121131897 
>>> t("""a[:]=[s.strip() for s in a]""", """a=[" %d " % s for s in range(10)]""") 
2.9129951000213623 
>>> t("""a=[s.strip() for s in a]""", """a=[" %d " % s for s in range(10)]""") 
2.47947096824646 
+0

Tại sao nói "được cho là hơi hiệu quả hơn" thay vì lược tả và kiểm tra? Và BTW '[:]' rất hữu ích bởi vì sau đó nó thay đổi cùng một danh sách, không gán lại biến cho một danh sách mới. – Kos

+2

Đó là * ít hiệu quả hơn vì nó phải sao chép N mục thay vì thay thế tham chiếu đến danh sách. "Lợi thế" duy nhất, mà bạn có thể không cần hoặc muốn, là sự thay đổi có thể nhìn thấy đối với bất kỳ ai có một tham chiếu khác đến đối tượng danh sách ban đầu. – delnan

+0

imho, không có gì lạ. –

18

Bạn có thể sử dụng danh sách comprehensions

stripped_list = [j.strip() for j in initial_list] 
+0

Bạn có nghĩ rằng việc hiểu danh sách giúp mã hoạt động nhanh hơn không? hoặc chỉ nhỏ hơn ?? – Surya

+0

Việc hiểu danh sách rất hiệu quả đối với đối tượng có thể lặp lại với các quy tắc đơn giản. Bạn có thể sử dụng bản đồ và danh sách hiểu tùy thuộc vào độ phức tạp. Nhưng có, họ cung cấp một thực hiện nhanh chóng và hiệu quả – karthikr

7

Một số cuộc thảo luận hấp dẫn về hoạt động xảy ra ở đây, vì vậy hãy để tôi cung cấp một chuẩn mực:

http://ideone.com/ldId8

noslice_map    : 0.0814900398254 
slice_map    : 0.084676027298 
noslice_comprehension : 0.0927240848541 
slice_comprehension  : 0.124806165695 
iter_manual    : 0.133514881134 
iter_enumerate   : 0.142778873444 
iter_range    : 0.160353899002 

Vì vậy:

  1. map(str.strip, my_list) là cách nhanh nhất, nó chỉ là một chút nhanh hơn hơn comperhensions.
    • Sử dụng map hoặc itertools.imap nếu có một chức năng duy nhất mà bạn muốn áp dụng (như str.split)
    • Sử dụng comprehensions nếu có một biểu hiện phức tạp hơn
  2. tay lặp đi lặp lại là cách chậm nhất; một lời giải thích hợp lý là nó yêu cầu người phiên dịch làm nhiều công việc hơn và thời gian chạy C hiệu quả ít hơn
  3. Hãy tiếp tục và gán kết quả như my_list[:] = map..., ký hiệu cắt lát chỉ giới thiệu một chi phí nhỏ và có khả năng cho bạn một số lỗi nếu có là nhiều tham chiếu đến danh sách đó.
    • Biết sự khác biệt giữa việc thay đổi danh sách và tạo lại danh sách.
+0

Bạn có nghĩa là 'my_list = map (str.strip, list [:])'? Bởi vì cách khác mang lại cho tôi một NameError. – Izkata

+0

Ý tôi là 'my_list [:] = map (str.strip, my_list)'. Xem mã dưới liên kết. – Kos

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