Какой самый эффективный способ перебора списка в Python?

Скажем, у меня есть список предметов:

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

Мне нужно выполнить некоторые функции для каждого из этих пунктов. В определенном случае мне нужно вернуть индекс элемента.

Какой самый лучший и самый эффективный способ?

for item in list:
    ....

или же

for i in range(len(list)):
    ....
 mankand00707 июн. 2012 г., 12:32
@sulabh: я не могу найти точную копию этого вопроса. Пожалуйста, ссылку то же самое. Вопрос, который я здесь задаю, - это сравнение двух разных способов итерации списка и предложение, которое лучше.
 jamylak07 июн. 2012 г., 12:34
@ mankand007 Ах, я вижу. Хорошо смотрите ответ, приведенный здесь. Вы можете сказать, просто посмотрев на них. Какой из них выглядит более читабельным для вас? Очевидно первый! В python вам обычно никогда не нужно перебирать массив по индексам.
 jamylak07 июн. 2012 г., 12:21
возможный дубликатIterate a list with indexes in python
 sulabh07 июн. 2012 г., 12:13
пожалуйста, ищите на форуме до публикации. На это ответили миллион раз
 mankand00707 июн. 2012 г., 12:44
если это не точный дубликат, то могут ли люди вернуть свои отрицательные голоса, пожалуйста? я бедный человек, понимаешь ...

Ответы на вопрос(4)

Решение Вопроса
for item in list:

это очевидно тот с меньшим количеством вызовов функции.

Если вы хотите получить индекс предметов по мере использованияперечислять как это

for pos, item in enumerate(collection):

очевидноfor i in range(len(list)): будет медленнее - это эквивалентно следующему:

list2 = range(len(list))

for i in list2:
    ...

Если бы это было быстрее, то это было бы еще быстрее, верно?

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

for i in list4:
    ...
def loop_1(data):
    for i in range(len(data)):
        print(data[i])


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

Проверка сдис дает нам следующий байт-код для 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        

Байт-код для loop_2 выглядит так:

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

Вторая версия явно лучше.

Другим возможным решением будет использованиеnumpy что было бы очень эффективно, для больших списков, возможно, даже более эффективно, чем понимание списка или цикл for.

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.])

Это довольно простая операция, но вы можете усложнить использование массива в качестве простого аргумента в формуле. Для больших массивов это может быть намного быстрее, чем понимание списка, и это делает код чище и легче для чтения (нет необходимости создавать функцию для отображения в понимании списка). Вы также можете использовать индексирование и нарезку, чтобы адаптировать то, что вы хотите сделать:

Если вы хотите иметь доступ к фактическим позициям индекса, используйте ndenumerate

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

Вывод этого цикла for:

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

ПРИМЕЧАНИЕ: индекс возвращается как кортеж по numpy для обработки дополнительных измерений. Здесь у нас есть только одно измерение, поэтому вам нужно распаковать кортеж, чтобы получить индекс элемента.

 07 июн. 2012 г., 22:50
Можете ли вы добавить какие-либо подробности об этом?

Ваш ответ на вопрос