Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 8354beb

Browse files
committed
Merge branch 'extend_lazy_lists' into t/19896/sequences/homogenous-seq
* extend_lazy_lists: simplify __repr__ code correct nasty bug in takewhile (complete rewrite of method) add a doctest in dropwhile fit start on iteration
2 parents 9b07780 + 3b63c47 commit 8354beb

File tree

2 files changed

+95
-32
lines changed

2 files changed

+95
-32
lines changed

src/sage/misc/lazy_list.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ cdef class lazy_list_from_update_function(lazy_list_generic):
2727
cdef class lazy_list_takewhile(lazy_list_generic):
2828
cdef object predicate
2929
cdef bint taking
30+
cdef Py_ssize_t to_test
3031

3132
cdef class lazy_list_dropwhile(lazy_list_generic):
3233
cdef object predicate

src/sage/misc/lazy_list.pyx

+94-32
Original file line numberDiff line numberDiff line change
@@ -589,20 +589,15 @@ cdef class lazy_list_generic(object):
589589
sage: lazy_list([0,1,2,3])
590590
lazy list [0, 1, 2, ...]
591591
"""
592-
cdef Py_ssize_t num_elts = 1 + (self.stop-self.start-1) / self.step
593-
cdef Py_ssize_t length = len(self.cache)
594-
595-
if (length <= self.start + self.preview*self.step and
596-
num_elts != length / self.step):
597-
self._fit(self.start + self.preview*self.step)
598-
num_elts = 1 + (self.stop-self.start-1) / self.step
599-
600592
cdef str s = self.name
601593
if s:
602594
s += ' '
603595
s += self.opening_delimiter
604-
cdef list E = list('{!r}'.format(self.get(n))
605-
for n in xrange(min(num_elts, self.preview)))
596+
cdef list P = list(self[:self.preview+1])
597+
cdef list E = list('{!r}'.format(e)
598+
for e in P[:self.preview])
599+
cdef Py_ssize_t num_elts = 1 + (self.stop-self.start-1) / self.step
600+
606601
if num_elts > self.preview:
607602
E.append(self.more)
608603
s += self.separator.join(E)
@@ -796,9 +791,16 @@ cdef class lazy_list_generic(object):
796791
start 0
797792
stop 5
798793
step 1
794+
795+
::
796+
797+
sage: tuple(lazy_list(Primes()).dropwhile(lambda x: x < 10)[:5])
798+
(11, 13, 17, 19, 23)
799799
"""
800800
cdef Py_ssize_t i
801801

802+
if self._fit(self.start):
803+
return
802804
i = self.start
803805
while i < self.stop:
804806
if self._fit(i):
@@ -1574,11 +1576,11 @@ cdef class lazy_list_takewhile(lazy_list_generic):
15741576
sage: lazy_list_takewhile(Z(), lambda x: x != 3)[4]
15751577
4
15761578
"""
1577-
15781579
lazy_list_generic.__init__(
15791580
self, master=master, cache=master._get_cache_(), **kwds)
15801581
self.predicate = predicate
15811582
self.taking = True
1583+
self.to_test = self.start
15821584

15831585

15841586
cpdef int update_cache_up_to(self, Py_ssize_t i) except -1:
@@ -1599,35 +1601,88 @@ cdef class lazy_list_takewhile(lazy_list_generic):
15991601
sage: L = lazy_list_takewhile(
16001602
....: lazy_list(Primes()), lambda x: x <= 10); L
16011603
lazy list [2, 3, 5, ...]
1604+
sage: L._info()
1605+
cache length 4
1606+
start 0
1607+
stop 9223372036854775807
1608+
step 1
16021609
sage: L.update_cache_up_to(10)
16031610
1
1611+
sage: tuple(L)
1612+
(2, 3, 5, 7)
16041613
sage: L._info()
16051614
cache length 5
16061615
start 0
16071616
stop 4
16081617
step 1
1618+
1619+
::
1620+
1621+
sage: P = lazy_list(Primes())
1622+
sage: a = tuple(P.dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20)); a
1623+
(11, 13, 17, 19)
1624+
sage: b = tuple(P.dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20))
1625+
sage: a == b
1626+
True
1627+
1628+
::
1629+
1630+
sage: F = lazy_list(lambda x: fibonacci(x))
1631+
sage: tuple(F.dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20))
1632+
(13,)
1633+
1634+
::
1635+
1636+
sage: P = lazy_list(srange(1,30,2))
1637+
sage: a = tuple(P.dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20)); a
1638+
(11, 13, 15, 17, 19)
1639+
sage: b = tuple(P.dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20))
1640+
sage: a == b
1641+
True
1642+
1643+
::
1644+
1645+
sage: P = lazy_list(Primes())
1646+
sage: Q = P.takewhile(lambda x: x < 20); c = tuple(Q); c
1647+
(2, 3, 5, 7, 11, 13, 17, 19)
1648+
sage: Q._info()
1649+
cache length 9
1650+
start 0
1651+
stop 8
1652+
step 1
1653+
sage: Q = P.takewhile(lambda x: x < 20); d = tuple(Q)
1654+
sage: Q._info()
1655+
cache length 9
1656+
start 0
1657+
stop 8
1658+
step 1
1659+
sage: c == d
1660+
True
16091661
"""
1610-
cdef Py_ssize_t length = len(self.cache)
16111662
if not self.taking:
1612-
if length <= i:
1613-
return 1
1614-
else:
1615-
return 0
1616-
cdef Py_ssize_t m
1617-
while length <= i:
1618-
if self.master._fit(length):
1619-
return 1
1620-
m = length
1621-
length = len(self.cache)
1622-
while m < length and self.predicate(self.cache[m]):
1623-
m += 1
1624-
if m < length:
1625-
self.stop = m
1663+
return 0
1664+
1665+
if self.master._fit(self.to_test):
1666+
self.stop = self.to_test
1667+
self.taking = False
1668+
return 1
1669+
self.to_test = max(self.to_test, self.start)
1670+
1671+
while self.to_test <= i:
1672+
if self.master._fit(self.to_test):
1673+
self.stop = self.to_test
16261674
self.taking = False
1627-
if m <= i:
1628-
return 1
1629-
else:
1630-
return 0
1675+
return 1
1676+
if not (self.to_test < len(self.cache) and
1677+
self.predicate(self.cache[self.to_test])):
1678+
break
1679+
self.to_test += 1
1680+
1681+
if self.to_test <= i:
1682+
self.stop = self.to_test
1683+
self.taking = False
1684+
return 1
1685+
16311686
return 0
16321687

16331688

@@ -1670,6 +1725,13 @@ cdef class lazy_list_dropwhile(lazy_list_generic):
16701725
start 6
16711726
stop 9223372036854775807
16721727
step 1
1728+
1729+
::
1730+
1731+
sage: lazy_list(Primes()).dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20)
1732+
lazy list [11, 13, 17, ...]
1733+
sage: tuple(lazy_list(Primes()).dropwhile(lambda x: x < 10).takewhile(lambda x: x < 20))
1734+
(11, 13, 17, 19)
16731735
"""
16741736
lazy_list_generic.__init__(
16751737
self, master=master, cache=master._get_cache_(), **kwds)
@@ -1711,8 +1773,8 @@ cdef class lazy_list_dropwhile(lazy_list_generic):
17111773
m = self.start
17121774
lazy_list_generic._fit(self, m)
17131775
while m < len(self.cache) and self.predicate(self.cache[m]):
1714-
m += 1
1715-
lazy_list_generic._fit(self, m)
1776+
m += 1
1777+
lazy_list_generic._fit(self, m)
17161778
self.start = m
17171779
self.dropping = False
17181780
n += m

0 commit comments

Comments
 (0)