Найти - Пользователи
Полная версия: Счетчик внутри цикла по итерируемому объекту
Начало » Python для новичков » Счетчик внутри цикла по итерируемому объекту
1
pasaranax
Иногда нужно знать номер итерации. Я тут придумал несколько способов, хочу чтобы вы оценили их со всех сторон и показали, что сами используете в подобных случаях.

1. Самый вроде бы логичный и питоник, но тормозной, на пару порядков отстает от следующих
for i in lst:
n = lst.index(i)
...
2. Так как-то не гламурно, по Сишному, некрасивая -1 некрасиво вылезает за цикл. А в другом случае, строка относящаяся больше к заголовку цикла стоит где-то в конце. Зато работает быстрее всех.
n = -1
for i in lst:
n += 1
...
# или
n = 0
for i in lst:
...
n += 1
3. Неплохой вариант, почти не уступающий по скорости первому, но втыкать исключение в таком случае как-то толсто, а pylint вообще ошибки засчитывает (он всегда так с исключениями?).
for i in lst:
try: n += 1
except UnboundLocalError: n = 0
...
4. Не уступает по скорости, но здесь как-то все наоборот, не питониковый цикл :)
for n in range(len(lst)):
i = lst[n]
...
regall
1. Если у тебя есть два одинаковых по значению элемента в списке, то метод index вернет тебе индекс первого попавшегося (так что по-моему такое вообще не катит, разве что есть уверенность, что все элементы уникальны).
2. Я лично всегда юзаю №4.
crchemist
pasaranax
1. Самый вроде бы логичный и питоник, но тормозной, на пару порядков отстает от следующих
for i in lst:
n = lst.index(i)
...
>>> lst = [1,2,3,1,2]
>>> for i in lst:
print lst.index(i)

0
1
2
0
1
>>>
треба так:
>>> lst = [1,2,3,1,2]
>>> for i,n in enumerate(lst):
print i, n

0 1
1 2
2 3
3 1
4 2
>>>
crchemist
pasaranax
4. Не уступает по скорости, но здесь как-то все наоборот, не питониковый цикл smile
for n in range(len(lst)):
i = lst[n]
...
і багато памяті жере
pasaranax
crchemist
спасибо, идеально :)
Griffon
Для тройки.
>>> t1 = Timer("""
lst = [1,2,3,0,1,2]*1000
for i in range(len(lst)):
elem = lst[i]
""")
>>> t2 = Timer("""
lst = [1,2,3,0,1,2]*1000
for i, v in enumerate(lst):
elem = v
""")
>>> t1.timeit(1000)
0.64110571315620746
>>> t1.timeit(1000)
0.6351636171635846
>>> t2.timeit(1000)
0.69831926962785928
>>> t2.timeit(1000)
0.69384705318691431
Для двойки можно использовать xrange.

Всегда использовал range. Но сейчас задумался.
crchemist, дякую.
crchemist
>>> s1 = """
for i in range(len(lst)):
elem = lst[i]
"""
>>> s2 = """
for i in xrange(len(lst)):
elem = lst[i]
"""
>>> s3 = """
for (i, v) in enumerate(lst):
elem = v
"""
>>> lst = [1,2,3,0,1,2]*1000

>>> setup = 'from __main__ import lst'
>>>
>>> t1 = Timer(s1, setup); t2 = Timer(s2, setup); t3 = Timer(s3, setup)
>>> t1.timeit(3000), t2.timeit(3000), t3.timeit(3000)
(1.9263118636586494, 1.6119261665937992, 1.9606022553145719)
>>> t1.timeit(3000), t2.timeit(3000), t3.timeit(3000)
(1.93520258859715, 1.6145745478824836, 1.9529405971988041)
чекав інших результатів…
тут питав - http://stackoverflow.com/questions/1352497/why-is-pythons-enumerate-so-slow
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB