@@ -785,8 +785,8 @@ well as with the built-in itertools such as ``map()``, ``filter()``,
785
785
786
786
A secondary purpose of the recipes is to serve as an incubator. The
787
787
``accumulate() ``, ``compress() ``, and ``pairwise() `` itertools started out as
788
- recipes. Currently, the ``sliding_window() `` and ``iter_index() `` recipes
789
- are being tested to see whether they prove their worth.
788
+ recipes. Currently, the ``sliding_window() ``, ``iter_index() ``, and `` sieve() ``
789
+ recipes are being tested to see whether they prove their worth.
790
790
791
791
Substantially all of these recipes and many, many others can be installed from
792
792
the `more-itertools project <https://pypi.org/project/more-itertools/ >`_ found
@@ -795,12 +795,12 @@ on the Python Package Index::
795
795
python -m pip install more-itertools
796
796
797
797
Many of the recipes offer the same high performance as the underlying toolset.
798
- Superior memory performance is kept by processing elements one at a time
799
- rather than bringing the whole iterable into memory all at once. Code volume is
800
- kept small by linking the tools together in a functional style which helps
801
- eliminate temporary variables. High speed is retained by preferring
802
- "vectorized" building blocks over the use of for-loops and :term: ` generator ` \s
803
- which incur interpreter overhead.
798
+ Superior memory performance is kept by processing elements one at a time rather
799
+ than bringing the whole iterable into memory all at once. Code volume is kept
800
+ small by linking the tools together in a ` functional style
801
+ <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf> `_. High speed
802
+ is retained by preferring "vectorized" building blocks over the use of for-loops
803
+ and :term: ` generators <generator> ` which incur interpreter overhead.
804
804
805
805
.. testcode ::
806
806
@@ -873,6 +873,14 @@ which incur interpreter overhead.
873
873
"Returns True if all the elements are equal to each other."
874
874
return len(take(2, groupby(iterable, key))) <= 1
875
875
876
+ def unique_justseen(iterable, key=None):
877
+ "List unique elements, preserving order. Remember only the element just seen."
878
+ # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
879
+ # unique_justseen('ABBcCAD', str.casefold) --> A B c A D
880
+ if key is None:
881
+ return map(operator.itemgetter(0), groupby(iterable))
882
+ return map(next, map(operator.itemgetter(1), groupby(iterable, key)))
883
+
876
884
def unique_everseen(iterable, key=None):
877
885
"List unique elements, preserving order. Remember all elements ever seen."
878
886
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
@@ -889,35 +897,6 @@ which incur interpreter overhead.
889
897
seen.add(k)
890
898
yield element
891
899
892
- def unique_justseen(iterable, key=None):
893
- "List unique elements, preserving order. Remember only the element just seen."
894
- # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
895
- # unique_justseen('ABBcCAD', str.casefold) --> A B c A D
896
- if key is None:
897
- return map(operator.itemgetter(0), groupby(iterable))
898
- return map(next, map(operator.itemgetter(1), groupby(iterable, key)))
899
-
900
- def iter_index(iterable, value, start=0, stop=None):
901
- "Return indices where a value occurs in a sequence or iterable."
902
- # iter_index('AABCADEAF', 'A') --> 0 1 4 7
903
- seq_index = getattr(iterable, 'index', None)
904
- if seq_index is None:
905
- # Path for general iterables
906
- it = islice(iterable, start, stop)
907
- for i, element in enumerate(it, start):
908
- if element is value or element == value:
909
- yield i
910
- else:
911
- # Path for sequences with an index() method
912
- stop = len(iterable) if stop is None else stop
913
- i = start
914
- try:
915
- while True:
916
- yield (i := seq_index(value, i, stop))
917
- i += 1
918
- except ValueError:
919
- pass
920
-
921
900
def sliding_window(iterable, n):
922
901
"Collect data into overlapping fixed-length chunks or blocks."
923
902
# sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG
@@ -967,6 +946,27 @@ which incur interpreter overhead.
967
946
slices = starmap(slice, combinations(range(len(seq) + 1), 2))
968
947
return map(operator.getitem, repeat(seq), slices)
969
948
949
+ def iter_index(iterable, value, start=0, stop=None):
950
+ "Return indices where a value occurs in a sequence or iterable."
951
+ # iter_index('AABCADEAF', 'A') --> 0 1 4 7
952
+ seq_index = getattr(iterable, 'index', None)
953
+ if seq_index is None:
954
+ # Path for general iterables
955
+ it = islice(iterable, start, stop)
956
+ for i, element in enumerate(it, start):
957
+ if element is value or element == value:
958
+ yield i
959
+ else:
960
+ # Path for sequences with an index() method
961
+ stop = len(iterable) if stop is None else stop
962
+ i = start
963
+ try:
964
+ while True:
965
+ yield (i := seq_index(value, i, stop))
966
+ i += 1
967
+ except ValueError:
968
+ pass
969
+
970
970
def iter_except(func, exception, first=None):
971
971
""" Call a function repeatedly until an exception is raised.
972
972
@@ -1047,8 +1047,8 @@ The following recipes have a more mathematical flavor:
1047
1047
1048
1048
Computes with better numeric stability than Horner's method.
1049
1049
"""
1050
- # Evaluate x³ -4x² -17x + 60 at x = 2. 5
1051
- # polynomial_eval([1, -4, -17, 60], x=2. 5) --> 8.125
1050
+ # Evaluate x³ -4x² -17x + 60 at x = 5
1051
+ # polynomial_eval([1, -4, -17, 60], x=5) --> 0
1052
1052
n = len(coefficients)
1053
1053
if not n:
1054
1054
return type(x)(0)
@@ -1311,10 +1311,10 @@ The following recipes have a more mathematical flavor:
1311
1311
1312
1312
>>> from fractions import Fraction
1313
1313
>>> from decimal import Decimal
1314
- >>> polynomial_eval([1 , - 4 , - 17 , 60 ], x = 2 )
1315
- 18
1316
- >>> x = 2 ; x** 3 - 4 * x** 2 - 17 * x + 60
1317
- 18
1314
+ >>> polynomial_eval([1 , - 4 , - 17 , 60 ], x = 5 )
1315
+ 0
1316
+ >>> x = 5 ; x** 3 - 4 * x** 2 - 17 * x + 60
1317
+ 0
1318
1318
>>> polynomial_eval([1 , - 4 , - 17 , 60 ], x = 2.5 )
1319
1319
8.125
1320
1320
>>> x = 2.5 ; x** 3 - 4 * x** 2 - 17 * x + 60
0 commit comments