Форум сайта python.su
всем привет у меня вот такого вида массив:
arr = [(1,2,3), (4,5,6), (8,9,10)]
if [v for v in arr if v[1] == 5]:
do_here_something()
Отредактировано (Авг. 13, 2009 06:35:27)
Офлайн
нет. Быстро не сделать, линейного времени поиска для списка не избежать. Мелкие ухищрения по крупному не помогут.
.index и .find - тоже имеют линейную алгоритмическую сложность
Возможно, лучше использовать другой тип данных?
Прямой ответ:
if 5 in (i[1] for i in lst):
do()
Отредактировано (Авг. 13, 2009 10:18:58)
Офлайн
А если классически, вот так, то это не быстрее будет?
for v in arr:
if v[1] == 5:
do_here_something()
Отредактировано (Авг. 13, 2009 12:31:55)
Офлайн
так - медленнее. И довольно ощутимо.
Но все же, как я говорил: если необходим поиск, используйте set или dict.
Кстати, в collections от Python 3.1 появился OrderedDict. Поскольку класс реализован на Питоне - можно его выдернуть и для более старых версий.
>>> from timeit import Timer
>>> import random
>>> l = [(str(i), i) for i in xrange(10000)]
>>> random.shuffle(l)
>>> s1 = 'if 5 in (i[1] for i in l): pass'
>>> t1 = Timer(s1, 'from __main__ import l')
>>> t1.timeit(1000)
0.59166409417957766
>>> s2 = 'if 5 in (i[1] for i in l): break'
>>> t2 = Timer(s2, 'from __main__ import l')
>>> t2.timeit(1000)
0.0012608446045305755
>>> s3 = '''
... for v in l:
... if 5 == v[1]:
... pass
... '''
...
>>> t3 = Timer(s3, 'from __main__ import l')
>>> t3.timeit(1000)
0.91812171658693842
>>> s4 = '''
... for v in l:
... if 5 == v[1]:
... break
... '''
>>> t4 = Timer(s4, 'from __main__ import l')
>>> t4.timeit(1000)
0.49133507191561421
>>>
Офлайн
а как это БРЕЙК в ифе? у меня на такую конструкцию питон 2.5 ругается
if 5 in (i[1] for i in l): break
Офлайн
Эт я слегка глюканул - так можно было писать только в контексте timeit. По хорошему Timer должен был дать мне по рукам - но не дал.
Офлайн
походу break выкидывает из цикла таймера
>>> s2 = 'if 5 in (i[1] for i in l): break'
>>> s22 = 'if 5 in (i[1] for i in l): pass'
>>> t2 = Timer(s2, 'from __main__ import l')
>>> t2.timeit(1000)
0.0017299652099609375
>>> t2.timeit(1000000000)
0.0017070770263671875
>>> t2 = Timer(s22, 'from __main__ import l')
>>> t2.timeit(1000)
1.6248788833618164
Офлайн