Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f373c6b

Browse files
authored
gh-107208: Fix iter_index() recipe to not swallow exceptions (gh-108835)
gh-107208: iter_index now supports "stop" and no longer swallows ValueError
1 parent a52213b commit f373c6b

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

Doc/library/itertools.rst

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -865,26 +865,22 @@ which incur interpreter overhead.
865865
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
866866
return next(filter(pred, iterable), default)
867867

868-
def iter_index(iterable, value, start=0):
868+
def iter_index(iterable, value, start=0, stop=None):
869869
"Return indices where a value occurs in a sequence or iterable."
870870
# iter_index('AABCADEAF', 'A') --> 0 1 4 7
871-
try:
872-
seq_index = iterable.index
873-
except AttributeError:
871+
seq_index = getattr(iterable, 'index', None)
872+
if seq_index is None:
874873
# Slow path for general iterables
875-
it = islice(iterable, start, None)
876-
i = start - 1
877-
try:
878-
while True:
879-
yield (i := i + operator.indexOf(it, value) + 1)
880-
except ValueError:
881-
pass
874+
it = islice(iterable, start, stop)
875+
for i, element in enumerate(it, start):
876+
if element is value or element == value:
877+
yield i
882878
else:
883879
# Fast path for sequences
884880
i = start - 1
885881
try:
886882
while True:
887-
yield (i := seq_index(value, i+1))
883+
yield (i := seq_index(value, i+1, stop))
888884
except ValueError:
889885
pass
890886

@@ -1331,6 +1327,21 @@ The following recipes have a more mathematical flavor:
13311327
[]
13321328
>>> list(iter_index(iter('AABCADEAF'), 'A', 10))
13331329
[]
1330+
>>> list(iter_index('AABCADEAF', 'A', 1, 7))
1331+
[1, 4]
1332+
>>> list(iter_index(iter('AABCADEAF'), 'A', 1, 7))
1333+
[1, 4]
1334+
>>> # Verify that ValueErrors not swallowed (gh-107208)
1335+
>>> def assert_no_value(iterable, forbidden_value):
1336+
... for item in iterable:
1337+
... if item == forbidden_value:
1338+
... raise ValueError
1339+
... yield item
1340+
...
1341+
>>> list(iter_index(assert_no_value('AABCADEAF', 'B'), 'A'))
1342+
Traceback (most recent call last):
1343+
...
1344+
ValueError
13341345

13351346
>>> list(sieve(30))
13361347
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

0 commit comments

Comments
 (0)