2012-06-07 34 views
11

Nói rằng tôi có một danh sách các mục:Cách nào hiệu quả nhất để lặp qua danh sách trong python?

x = [1, 2, 3, 4, 5] 

tôi cần phải thực hiện một số chức năng cho mỗi người trong số các mặt hàng này. Trong một trường hợp nhất định, tôi cần trả về chỉ mục của một mục.

Cách nào là tốt nhất và hiệu quả nhất?

for item in list: 
    .... 

hoặc

for i in range(len(list)): 
    .... 
+3

vui lòng tìm kiếm bài đăng trên diễn đàn. Điều này đã được trả lời một triệu lần – sulabh

+0

có thể trùng lặp của [Iterate một danh sách với các chỉ mục trong python] (http: // stackoverflow.com/questions/126524/iterate-a-list-với-index-in-python) – jamylak

+0

@sulabh: Tôi không tìm thấy bản sao chính xác của câu hỏi này. Vui lòng liên kết giống nhau. Các câu hỏi ở đây tôi hỏi là một so sánh giữa hai cách khác nhau của iterating một danh sách, và một đề nghị trong đó là tốt hơn. – mankand007

Trả lời

10
for item in list: 

rõ ràng của nó một với ít chức năng cuộc gọi.

Nếu bạn muốn để có được những chỉ số của mặt hàng như bạn đi sử dụng enumerate như thế này

for pos, item in enumerate(collection): 
8
def loop_1(data): 
    for i in range(len(data)): 
     print(data[i]) 


def looper_2(data): 
    for val in data: 
     print(val) 

Kiểm tra với dis cho chúng ta bytecode sau cho loop_1:

12  0 SETUP_LOOP    40 (to 43) 
      3 LOAD_GLOBAL    0 (range) 
      6 LOAD_GLOBAL    1 (len) 
      9 LOAD_FAST    0 (data) 
     12 CALL_FUNCTION   1 
     15 CALL_FUNCTION   1 
     18 GET_ITER    
    >> 19 FOR_ITER    20 (to 42) 
     22 STORE_FAST    1 (i) 

13  25 LOAD_GLOBAL    2 (print) 
     28 LOAD_FAST    0 (data) 
     31 LOAD_FAST    1 (i) 
     34 BINARY_SUBSCR  
     35 CALL_FUNCTION   1 
     38 POP_TOP    
     39 JUMP_ABSOLUTE   19 
    >> 42 POP_BLOCK   
    >> 43 LOAD_CONST    0 (None) 
     46 RETURN_VALUE   

Bytecode cho loop_2 trông giống như sau:

17  0 SETUP_LOOP    24 (to 27) 
      3 LOAD_FAST    0 (data) 
      6 GET_ITER    
    >> 7 FOR_ITER    16 (to 26) 
     10 STORE_FAST    1 (val) 

18  13 LOAD_GLOBAL    0 (print) 
     16 LOAD_FAST    1 (val) 
     19 CALL_FUNCTION   1 
     22 POP_TOP    
     23 JUMP_ABSOLUTE   7 
    >> 26 POP_BLOCK   
    >> 27 LOAD_CONST    0 (None) 
     30 RETURN_VALUE 

Phiên bản thứ hai rõ ràng là tốt hơn.

2

Rõ ràng for i in range(len(list)): sẽ chậm hơn - đó là tương đương với điều này:

list2 = range(len(list)) 

for i in list2: 
    ... 

Nếu đó là nhanh hơn, thì đây sẽ là thậm chí nhanh hơn, phải không?

list2 = range(len(list)) 
list3 = range(len(list2)) 
list4 = range(len(list3)) 

for i in list4: 
    ... 
4

Một giải pháp khác có thể là sử dụng numpy sẽ rất hiệu quả, cho các danh sách lớn thậm chí còn hiệu quả hơn so với danh sách hiểu hoặc vòng lặp.

import numpy as np 

a = np.arange(5.0) # a --> array([0., 1., 2., 3., 4.]) 

# numpy operates on arrays element by element 
# 
b =3.*a    # b --> array([0., 3., 6., 9., 12.]) 

Đây là một thao tác khá đơn giản nhưng bạn có thể phức tạp hơn bằng cách sử dụng mảng đơn giản như một đối số trong công thức. Đối với mảng lớn, điều này có thể nhanh hơn nhiều so với việc đọc danh sách và nó làm cho mã sạch hơn và dễ đọc hơn (không cần phải tạo một hàm để ánh xạ trong một danh sách hiểu). Bạn cũng có thể sử dụng chỉ mục và cắt điều chỉnh những gì bạn muốn làm:

Nếu bạn muốn có quyền truy cập vào các vị trí chỉ số thực tế sử dụng ndenumerate

# b is as above 
for i, x in np.ndenumerate(b): 
    print i, x 

Kết quả của điều này cho vòng lặp là:

(0,) 0.0 
(1,) 3.0 
(2,) 6.0 
(3,) 9.0 
(4,) 12.0 

LƯU Ý: chỉ mục được trả về dưới dạng bộ dữ liệu bằng cách numpy để xử lý thứ nguyên bổ sung. Ở đây chúng ta chỉ có một chiều duy nhất để bạn phải giải nén tuple để lấy chỉ mục của phần tử.

+1

Bạn có thể thêm bất kỳ chi tiết nào về điều này không? –

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