Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Общие вопросы > itertools.takewhile()


Автор: setq 18.5.2006, 13:56
Функция takewhile из модуля itertools отбирает несколько первых элементов "последовательности", которые удовлетворяют заданному условию. Но она также "выкидывает" элемент, который не подошёл по условию. Вот, ломаю голову над тем как это обойти и оставлять этот элемент.

Пример:
Код

>>> import itertools
>>> a = range(10)
>>> a = iter(a)
>>> b = itertools.takewhile(lambda x: x<5, a)
>>> print list(b)
[0, 1, 2, 3, 4]
>>> print list(a)  # смотрите: нет 5!
[6, 7, 8, 9]
 

Автор: slav0nic 18.5.2006, 16:47
хм, странно, эта ф-ция аналогична
Код

def takewhile(predicate, iterable):
         for x in iterable:
             if predicate(x):
                 yield x
             else:
                 break

если сделать
Код

b = takewhile(lambda x: x<5, a)
print  list(b),list(a)
print  list(b),list(a)

результат:
[0, 1, 2, 3, 4] [6, 7, 8, 9]
[] []
если заменить a=xrange(10)
[0, 1, 2, 3, 4] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
видать проблема в итераторах (редко их юзаю=) )
нихрена не понимаю блин)


  

Автор: slav0nic 19.5.2006, 14:41
по идее в генераторе до break срабатывает итератор, после только после чего вроисходит break и 5 просто теряется) 

Код

>>> a = iter(range(10))
>>> len(a)
10
>>> for x in a:
...     if x<5:
...             print list(a),x

[1, 2, 3, 4, 5, 6, 7, 8, 9] 0

а если потом брык, то 0 потерялся бы
вроде всё так

 

Автор: setq 19.5.2006, 17:24
Чего? Ладно smile спасибо. Есть идея переписать takewhile() с глобальной переменной, куда сохранялся бы потерянный элемент, но она по-моему фиговая - эта идея. Ещё есть идея написать свой класс Итератор с методом takewhile(), но это не дзен. По-моему. Вот. 

Автор: slav0nic 19.5.2006, 17:52
есть идея не юзать итераторы;) а написать по простому
Код

a = xrange(10)
b = filter(lambda x: x<5, a)
a = filter(lambda x:x>=5, a)

самое тупое) 

Автор: setq 19.5.2006, 18:44
С радостью бы. Но мои "итераторы" по 20 миллионов длиной. Их за раз в память не поднять. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)