Найти - Пользователи
Полная версия: Прерывание цыкла генератора
Начало » Python для экспертов » Прерывание цыкла генератора
1 2 3 4
FishHook
В некоторых случаях генераторы списков существенно обгоняют даже map+filter, не то что for, ввиду отсутствия необходимости вызывать функцию
def foo(x):
    return x % 2
def bar(x):
    return x > 10
def func1():
     lst = [foo(x) for x in xrange(10000000) if bar(x)]
def func2():
     lst = filter(bar, map(foo, xrange(10000000)))
t1 = timeit.Timer(func1, 'from __main__ import func1, foo')
t2 = timeit.Timer(func2, 'from __main__ import func2, foo')
print t1.timeit(1)
print t2.timeit(1)
2.43812799454
2.16352391243

# -*- coding:utf-8 -*-
import timeit
....
def func1():
     lst = [x % 2 for x in xrange(10000000) if x > 10]
def func2():
     lst = filter(bar, map(foo, xrange(10000000)))
....
0.842472791672
2.13915705681
def func1():
     lst = [x % 2 for x in xrange(10000000) if x > 10]
def func2():
     lst = filter(lambda x: x > 10, map(lambda x: x % 2, xrange(10000000)))
0.844331979752
2.1546831131
VadimR
user_uid = '10002'
user_name = next(x.split(':')[0] for x in open('passwd.txt') if x.split(':')[2] == user_uid)
print(user_name)
py.user.next
PooH
Имеется ввиду, что после того, как он найдет нужный элемент, итерация все равно будет выполнена до конца.
c чего это ?
итераторы для того и делались, чтобы их до конца не выполнять

например, itertools.count() - бесконечный итератор

>>> import itertools
>>> it = itertools.count()
>>> next(it)
0
>>> next(it)
1
>>> next(it)
2
>>>

так же и с файлами, они - итераторы по строкам
filter() приведена для третьего питона, в нём это itertools.ifilter(), перенесённая в ядро


FishHook
В некоторых случаях генераторы списков существенно обгоняют даже map+filter, не то что for, ввиду отсутствия необходимости вызывать функцию
это не из-за этого, во втором питоне эти функции создают списки, которые потом используются для перебора (создания итераторов)
поэтому как filter(), так и map() нужно заменить на аналоги из itertools
и уже тогда сравнивать
Budulianin
py.user.next
поэтому как filter(), так и map() нужно заменить на аналоги из itertools
и уже тогда сравнивать

import timeit
from itertools import ifilter, imap
def foo(x):
    return x % 2
def bar(x):
    return x > 0
    
def func1():
     sum( [foo(x) for x in xrange(100000) if bar(x)] )
     
def func2():
     sum( ifilter(bar, imap(foo, xrange(100000))) )
     
t1 = timeit.Timer(func1, 'from __main__ import func1, foo')
t2 = timeit.Timer(func2, 'from __main__ import func2, foo')
print t1.repeat(3, 10)
print t2.repeat(3, 10)

[0.6189520359039307, 0.6175930500030518, 0.620582103729248]
[0.568681001663208, 0.5698568820953369, 0.5771739482879639]


def func1():
     sum( [x % 2 for x in xrange(100000) if x > 0] )
    
def func2():
     sum( ifilter(lambda x: x > 0, imap(lambda x: x % 2, xrange(100000))) )
     

[0.20290303230285645, 0.2011399269104004, 0.19998598098754883]
[0.5880811214447021, 0.5824930667877197, 0.5833539962768555]
Budulianin
py.user.next
это не из-за этого, во втором питоне эти функции создают списки, которые потом используются для перебора (создания итераторов)
поэтому как filter(), так и map() нужно заменить на аналоги из itertools
и уже тогда сравнивать

Как видно, вызов функций, тоже замедляет работу
py.user.next
Budulianin
[0.6189520359039307, 0.6175930500030518, 0.620582103729248]
[0.568681001663208, 0.5698568820953369, 0.5771739482879639]
ну вот, что и требовалось доказать

Budulianin
Как видно, вызов функций, тоже замедляет работу
во втором случае коды не эквивалентные
хочешь сравнить - возьми включение с функцией и включение без функции - их и сравнивай
Budulianin
py.user.next
во втором случае коды не эквивалентные
хочешь сравнить - возьми включение с функцией и включение без функции - их и сравнивай

Без imap в filter? Генератор списка всё равно быстрее будет
FishHook
py.user.next
нужно заменить на аналоги из itertools
и уже тогда сравнивать
Не согласен, в этом случае сравнивать надо не
[x for x ]
, а
(x for x)
py.user.next
FishHook
Не согласен, в этом случае сравнивать надо не
это да, не думаю, что будут сильно различаться
можно для второй функции list сделать

Budulianin, убери скобки возле return, не позорься
сначала убери скобки, запомни это
а потом и весь return убери и lst = тоже - не нужно это всё для замеров
Budulianin
py.user.next

На счёт того, что return и lst = не нужны для замеров, это понятно

А что позорного в return() ? Если интерпретатор это понимает
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