@@ -777,8 +777,8 @@ well as with the built-in itertools such as ``map()``, ``filter()``,
777
777
778
778
A secondary purpose of the recipes is to serve as an incubator. The
779
779
``accumulate() ``, ``compress() ``, and ``pairwise() `` itertools started out as
780
- recipes. Currently, the ``sliding_window() `` and ``iter_index() `` recipes
781
- are being tested to see whether they prove their worth.
780
+ recipes. Currently, the ``sliding_window() ``, ``iter_index() ``, and `` sieve() ``
781
+ recipes are being tested to see whether they prove their worth.
782
782
783
783
Substantially all of these recipes and many, many others can be installed from
784
784
the `more-itertools project <https://pypi.org/project/more-itertools/ >`_ found
@@ -787,12 +787,12 @@ on the Python Package Index::
787
787
python -m pip install more-itertools
788
788
789
789
Many of the recipes offer the same high performance as the underlying toolset.
790
- Superior memory performance is kept by processing elements one at a time
791
- rather than bringing the whole iterable into memory all at once. Code volume is
792
- kept small by linking the tools together in a functional style which helps
793
- eliminate temporary variables. High speed is retained by preferring
794
- "vectorized" building blocks over the use of for-loops and :term: ` generator ` \s
795
- which incur interpreter overhead.
790
+ Superior memory performance is kept by processing elements one at a time rather
791
+ than bringing the whole iterable into memory all at once. Code volume is kept
792
+ small by linking the tools together in a ` functional style
793
+ <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf> `_. High speed
794
+ is retained by preferring "vectorized" building blocks over the use of for-loops
795
+ and :term: ` generators <generator> ` which incur interpreter overhead.
796
796
797
797
.. testcode ::
798
798
@@ -865,6 +865,14 @@ which incur interpreter overhead.
865
865
"Returns True if all the elements are equal to each other."
866
866
return len(take(2, groupby(iterable, key))) <= 1
867
867
868
+ def unique_justseen(iterable, key=None):
869
+ "List unique elements, preserving order. Remember only the element just seen."
870
+ # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
871
+ # unique_justseen('ABBcCAD', str.casefold) --> A B c A D
872
+ if key is None:
873
+ return map(operator.itemgetter(0), groupby(iterable))
874
+ return map(next, map(operator.itemgetter(1), groupby(iterable, key)))
875
+
868
876
def unique_everseen(iterable, key=None):
869
877
"List unique elements, preserving order. Remember all elements ever seen."
870
878
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
@@ -881,35 +889,6 @@ which incur interpreter overhead.
881
889
seen.add(k)
882
890
yield element
883
891
884
- def unique_justseen(iterable, key=None):
885
- "List unique elements, preserving order. Remember only the element just seen."
886
- # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
887
- # unique_justseen('ABBcCAD', str.casefold) --> A B c A D
888
- if key is None:
889
- return map(operator.itemgetter(0), groupby(iterable))
890
- return map(next, map(operator.itemgetter(1), groupby(iterable, key)))
<
10000
code>891
-
892
- def iter_index(iterable, value, start=0, stop=None):
893
- "Return indices where a value occurs in a sequence or iterable."
894
- # iter_index('AABCADEAF', 'A') --> 0 1 4 7
895
- seq_index = getattr(iterable, 'index', None)
896
- if seq_index is None:
897
- # Path for general iterables
898
- it = islice(iterable, start, stop)
899
- for i, element in enumerate(it, start):
900
- if element is value or element == value:
901
- yield i
902
- else:
903
- # Path for sequences with an index() method
904
- stop = len(iterable) if stop is None else stop
905
- i = start
906
- try:
907
- while True:
908
- yield (i := seq_index(value, i, stop))
909
- i += 1
910
- except ValueError:
911
- pass
912
-
913
892
def sliding_window(iterable, n):
914
893
"Collect data into overlapping fixed-length chunks or blocks."
915
894
# sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG
@@ -959,6 +938,27 @@ which incur interpreter overhead.
959
938
slices = starmap(slice, combinations(range(len(seq) + 1), 2))
960
939
return map(operator.getitem, repeat(seq), slices)
961
940
941
+ def iter_index(iterable, value, start=0, stop=None):
942
+ "Return indices where a value occurs in a sequence or iterable."
943
+ # iter_index('AABCADEAF', 'A') --> 0 1 4 7
944
+ seq_index = getattr(iterable, 'index', None)
945
+ if seq_index is None:
946
+ # Path for general iterables
947
+ it = islice(iterable, start, stop)
948
+ for i, element in enumerate(it, start):
949
+ if element is value or element == value:
950
+ yield i
951
+ else:
952
+ # Path for sequences with an index() method
953
+ stop = len(iterable) if stop is None else stop
954
+ i = start
955
+ try:
956
+ while True:
957
+ yield (i := seq_index(value, i, stop))
958
+ i += 1
959
+ except ValueError:
960
+ pass
961
+
962
962
def iter_except(func, exception, first=None):
963
963
""" Call a function repeatedly until an exception is raised.
964
964
@@ -1039,8 +1039,8 @@ The following recipes have a more mathematical flavor:
1039
1039
1040
1040
Computes with better numeric stability than Horner's method.
1041
1041
"""
1042
- # Evaluate x³ -4x² -17x + 60 at x = 2. 5
1043
- # polynomial_eval([1, -4, -17, 60], x=2. 5) --> 8.125
1042
+ # Evaluate x³ -4x² -17x + 60 at x = 5
1043
+ # polynomial_eval([1, -4, -17, 60], x=5) --> 0
1044
1044
n = len(coefficients)
1045
1045
if not n:
1046
1046
return type(x)(0)
@@ -1299,10 +1299,10 @@ The following recipes have a more mathematical flavor:
1299
1299
1300
1300
>>> from fractions import Fraction
1301
1301
>>> from decimal import Decimal
1302
- >>> polynomial_eval([1 , - 4 , - 17 , 60 ], x = 2 )
1303
- 18
1304
- >>> x = 2 ; x** 3 - 4 * x** 2 - 17 * x + 60
1305
- 18
1302
+ >>> polynomial_eval([1 , - 4 , - 17 , 60 ], x = 5 )
1303
+ 0
1304
+ >>> x = 5 ; x** 3 - 4 * x** 2 - 17 * x + 60
1305
+ 0
1306
1306
>>> polynomial_eval([1 , - 4 , - 17 , 60 ], x = 2.5 )
1307
1307
8.125
1308
1308
>>> x = 2.5 ; x** 3 - 4 * x** 2 - 17 * x + 60
0 commit comments