Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 27, 2009 21:39:58

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

Иногда нужно знать номер итерации. Я тут придумал несколько способов, хочу чтобы вы оценили их со всех сторон и показали, что сами используете в подобных случаях.

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



Отредактировано (Авг. 27, 2009 21:44:13)

Офлайн

#2 Авг. 27, 2009 21:55:49

regall
От: Киев
Зарегистрирован: 2008-07-17
Сообщения: 1583
Репутация: +  3  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

1. Если у тебя есть два одинаковых по значению элемента в списке, то метод index вернет тебе индекс первого попавшегося (так что по-моему такое вообще не катит, разве что есть уверенность, что все элементы уникальны).
2. Я лично всегда юзаю №4.



Офлайн

#3 Авг. 27, 2009 22:00:48

crchemist
От:
Зарегистрирован: 2008-07-09
Сообщения: 379
Репутация: +  0  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

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
>>>



Офлайн

#4 Авг. 27, 2009 22:07:56

crchemist
От:
Зарегистрирован: 2008-07-09
Сообщения: 379
Репутация: +  0  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

pasaranax
4. Не уступает по скорости, но здесь как-то все наоборот, не питониковый цикл smile
for n in range(len(lst)):
i = lst[n]
...
і багато памяті жере



Офлайн

#5 Авг. 27, 2009 23:40:04

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

crchemist
спасибо, идеально :)



Офлайн

#6 Авг. 29, 2009 08:38:49

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

Для тройки.

>>> 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, дякую.



Отредактировано (Авг. 29, 2009 08:41:23)

Офлайн

#7 Авг. 29, 2009 23:22:46

crchemist
От:
Зарегистрирован: 2008-07-09
Сообщения: 379
Репутация: +  0  -
Профиль   Отправить e-mail  

Счетчик внутри цикла по итерируемому объекту

>>> 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



Отредактировано (Авг. 30, 2009 01:51:03)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version