@@ -659,54 +659,6 @@ This can also be written as a list comprehension:
659659 >>> list (x for x in range (10 ) if is_even(x))
660660 [0, 2, 4, 6, 8]
661661
662- ``functools.reduce(func, iter, [initial_value]) `` cumulatively performs an
663- operation on all the iterable's elements and, therefore, can't be applied to
664- infinite iterables. (Note it is not in :mod: `builtins `, but in the
665- :mod: `functools ` module.) ``func `` must be a function that takes two elements
666- and returns a single value. :func: `functools.reduce ` takes the first two
667- elements A and B returned by the iterator and calculates ``func(A, B) ``. It
668- then requests the third element, C, calculates ``func(func(A, B), C) ``, combines
669- this result with the fourth element returned, and continues until the iterable
670- is exhausted. If the iterable returns no values at all, a :exc: `TypeError `
671- exception is raised. If the initial value is supplied, it's used as a starting
672- point and ``func(initial_value, A) `` is the first calculation. ::
673-
674- >>> import operator, functools
675- >>> functools.reduce(operator.concat, ['A', 'BB', 'C'])
676- 'ABBC'
677- >>> functools.reduce(operator.concat, [])
678- Traceback (most recent call last):
679- ...
680- TypeError: reduce() of empty sequence with no initial value
681- >>> functools.reduce(operator.mul, [1,2,3], 1)
682- 6
683- >>> functools.reduce(operator.mul, [], 1)
684- 1
685-
686- If you use :func: `operator.add ` with :func: `functools.reduce `, you'll add up all the
687- elements of the iterable. This case is so common that there's a special
688- built-in called :func: `sum ` to compute it:
689-
690- >>> import functools
691- >>> functools.reduce(operator.add, [1 ,2 ,3 ,4 ], 0 )
692- 10
693- >>> sum ([1 ,2 ,3 ,4 ])
694- 10
695- >>> sum ([])
696- 0
697-
698- For many uses of :func: `functools.reduce `, though, it can be clearer to just write the
699- obvious :keyword: `for ` loop::
700-
701- import functools
702- # Instead of:
703- product = functools.reduce(operator.mul, [1,2,3], 1)
704-
705- # You can write:
706- product = 1
707- for i in [1,2,3]:
708- product *= i
709-
710662
711663``enumerate(iter) `` counts off the elements in the iterable, returning 2-tuples
712664containing the count and each element. ::
@@ -744,6 +696,7 @@ the constructed list's ``.sort()`` method. ::
744696(For a more detailed discussion of sorting, see the Sorting mini-HOWTO in the
745697Python wiki at http://wiki.python.org/moin/HowTo/Sorting.)
746698
699+
747700The ``any(iter) `` and ``all(iter) `` built-ins look at the truth values of an
748701iterable's contents. :func: `any ` returns True if any element in the iterable is
749702a true value, and :func: `all ` returns True if all of the elements are true
@@ -763,90 +716,27 @@ values:
763716 True
764717
765718
766- Small functions and the lambda expression
767- =========================================
768-
769- When writing functional-style programs, you'll often need little functions that
770- act as predicates or that combine elements in some way.
771-
772- If there's a Python built-in or a module function that's suitable, you don't
773- need to define a new function at all::
774-
775- stripped_lines = [line.strip() for line in lines]
776- existing_files = filter(os.path.exists, file_list)
777-
778- If the function you need doesn't exist, you need to write it. One way to write
779- small functions is to use the ``lambda `` statement. ``lambda `` takes a number
780- of parameters and an expression combining these parameters, and creates a small
781- function that returns the value of the expression::
782-
783- lowercase = lambda x: x.lower()
784-
785- print_assign = lambda name, value: name + '=' + str(value)
786-
787- adder = lambda x, y: x+y
788-
789- An alternative is to just use the ``def `` statement and define a function in the
790- usual way::
791-
792- def lowercase(x):
793- return x.lower()
794-
795- def print_assign(name, value):
796- return name + '=' + str(value)
797-
798- def adder(x,y):
799- return x + y
800-
801- Which alternative is preferable? That's a style question; my usual course is to
802- avoid using ``lambda ``.
803-
804- One reason for my preference is that ``lambda `` is quite limited in the
805- functions it can define. The result has to be computable as a single
806- expression, which means you can't have multiway ``if... elif... else ``
807- comparisons or ``try... except `` statements. If you try to do too much in a
808- ``lambda `` statement, you'll end up with an overly complicated expression that's
809- hard to read. Quick, what's the following code doing?
810-
811- ::
812-
813- import functools
814- total = functools.reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
815-
816- You can figure it out, but it takes time to disentangle the expression to figure
817- out what's going on. Using a short nested ``def `` statements makes things a
818- little bit better::
819-
820- import functools
821- def combine (a, b):
822- return 0, a[1] + b[1]
823-
824- total = functools.reduce(combine, items)[1]
825-
826- But it would be best of all if I had simply used a ``for `` loop::
827-
828- total = 0
829- for a, b in items:
830- total += b
831-
832- Or the :func: `sum ` built-in and a generator expression::
719+ ``zip(iterA, iterB, ...) `` takes one element from each iterable and
720+ returns them in a tuple::
833721
834- total = sum(b for a,b in items)
722+ zip(['a', 'b', 'c'], (1, 2, 3)) =>
723+ ('a', 1), ('b', 2), ('c', 3)
835724
836- Many uses of :func: `functools.reduce ` are clearer when written as ``for `` loops.
725+ It doesn't construct an in-memory list and exhaust all the input iterators
726+ before returning; instead tuples are constructed and returned only if they're
727+ requested. (The technical term for this behaviour is `lazy evaluation
728+ <http://en.wikipedia.org/wiki/Lazy_evaluation> `__.)
837729
838- Fredrik Lundh once suggested the following set of rules for refactoring uses of
839- ``lambda ``:
730+ This iterator is intended to be used with iterables that are all of the same
731+ length. If the iterables are of different lengths, the resulting stream will be
732+ the same length as the shortest iterable. ::
840733
841- 1) Write a lambda function.
842- 2) Write a comment explaining what the heck that lambda does.
843- 3) Study the comment for a while, and think of a name that captures the essence
844- of the comment.
845- 4) Convert the lambda to a def statement, using that name.
846- 5) Remove the comment.
734+ zip(['a', 'b'], (1, 2, 3)) =>
735+ ('a', 1), ('b', 2)
847736
848- I really like these rules, but you're free to disagree
849- about whether this lambda-free style is better.
737+ You should avoid doing this, though, because an element may be taken from the
738+ longer iterators and discarded. This means you can't go on to use the iterators
739+ further because you risk skipping a discarded element.
850740
851741
852742The itertools module
@@ -896,29 +786,6 @@ of the second, and so on, until all of the iterables have been exhausted. ::
896786 itertools.chain(['a', 'b', 'c'], (1, 2, 3)) =>
897787 a, b, c, 1, 2, 3
898788
899- ``itertools.izip(iterA, iterB, ...) `` takes one element from each iterable and
900- returns them in a tuple::
901-
902- itertools.izip(['a', 'b', 'c'], (1, 2, 3)) =>
903- ('a', 1), ('b', 2), ('c', 3)
904-
905- It's similar to the built-in :func: `zip ` function, but doesn't construct an
906- in-memory list and exhaust all the input iterators before returning; instead
907- tuples are constructed and returned only if they're requested. (The technical
908- term for this behaviour is `lazy evaluation
909- <http://en.wikipedia.org/wiki/Lazy_evaluation> `__.)
910-
911- This iterator is intended to be used with iterables that are all of the same
912- length. If the iterables are of different lengths, the resulting stream will be
913- the same length as the shortest iterable. ::
914-
915- itertools.izip(['a', 'b'], (1, 2, 3)) =>
916- ('a', 1), ('b', 2)
917-
918- You should avoid doing this, though, because an element may be taken from the
919- longer iterators and discarded. This means you can't go on to use the iterators
920- further because you risk skipping a discarded element.
921-
922789``itertools.islice(iter, [start], stop, [step]) `` returns a stream that's a
923790slice of the iterator. With a single ``stop `` argument, it will return the
924791first ``stop `` elements. If you supply a starting index, you'll get
@@ -953,8 +820,6 @@ consumed more than the others. ::
953820Calling functions on elements
954821-----------------------------
955822
956- ``itertools.imap(func, iter) `` is the same as built-in :func: `map `.
957-
958823The ``operator `` module contains a set of functions corresponding to Python's
959824operators. Some examples are ``operator.add(a, b) `` (adds two values),
960825``operator.ne(a, b) `` (same as ``a!=b ``), and ``operator.attrgetter('id') ``
@@ -976,12 +841,10 @@ Selecting elements
976841Another group of functions chooses a subset of an iterator's elements based on a
977842predicate.
978843
979- ``itertools.ifilter(predicate, iter) `` is the same as built-in :func: `filter `.
980-
981- ``itertools.ifilterfalse(predicate, iter) `` is the opposite, returning all
844+ ``itertools.filterfalse(predicate, iter) `` is the opposite, returning all
982845elements for which the predicate returns false::
983846
984- itertools.ifilterfalse (is_even, itertools.count()) =>
847+ itertools.filterfalse (is_even, itertools.count()) =>
985848 1, 3, 5, 7, 9, 11, 13, 15, ...
986849
987850``itertools.takewhile(predicate, iter) `` returns elements for as long as the
@@ -1083,6 +946,54 @@ Here's a small but realistic example::
1083946 server_log = functools.partial(log, subsystem='server')
1084947 server_log('Unable to open socket')
1085948
949+ ``functools.reduce(func, iter, [initial_value]) `` cumulatively performs an
950+ operation on all the iterable's elements and, therefore, can't be applied to
951+ infinite iterables. (Note it is not in :mod: `builtins `, but in the
952+ :mod: `functools ` module.) ``func `` must be a function that takes two elements
953+ and returns a single value. :func: `functools.reduce ` takes the first two
954+ elements A and B returned by the iterator and calculates ``func(A, B) ``. It
955+ then requests the third element, C, calculates ``func(func(A, B), C) ``, combines
956+ this result with the fourth element returned, and continues until the iterable
957+ is exhausted. If the iterable returns no values at all, a :exc: `TypeError `
958+ exception is raised. If the initial value is supplied, it's used as a starting
959+ point and ``func(initial_value, A) `` is the first calculation. ::
960+
961+ >>> import operator, functools
962+ >>> functools.reduce(operator.concat, ['A', 'BB', 'C'])
963+ 'ABBC'
964+ >>> functools.reduce(operator.concat, [])
965+ Traceback (most recent call last):
966+ ...
967+ TypeError: reduce() of empty sequence with no initial value
968+ >>> functools.reduce(operator.mul, [1,2,3], 1)
969+ 6
970+ >>> functools.reduce(operator.mul, [], 1)
971+ 1
972+
973+ If you use :func: `operator.add ` with :func: `functools.reduce `, you'll add up all the
974+ elements of the iterable. This case is so common that there's a special
975+ built-in called :func: `sum ` to compute it:
976+
977+ >>> import functools
978+ >>> functools.reduce(operator.add, [1 ,2 ,3 ,4 ], 0 )
979+ 10
980+ >>> sum ([1 ,2 ,3 ,4 ])
981+ 10
982+ >>> sum ([])
983+ 0
984+
985+ For many uses of :func: `functools.reduce `, though, it can be clearer to just write the
986+ obvious :keyword: `for ` loop::
987+
988+ import functools
989+ # Instead of:
990+ product = functools.reduce(operator.mul, [1,2,3], 1)
991+
992+ # You can write:
993+ product = 1
994+ for i in [1,2,3]:
995+ product *= i
996+
1086997
1087998The operator module
1088999-------------------
@@ -1232,6 +1143,92 @@ idiom::
12321143 join = partial(foldl, concat, "")
12331144
12341145
1146+ Small functions and the lambda expression
1147+ =========================================
1148+
1149+ When writing functional-style programs, you'll often need little functions that
1150+ act as predicates or that combine elements in some way.
1151+
1152+ If there's a Python built-in or a module function that's suitable, you don't
1153+ need to define a new function at all::
1154+
1155+ stripped_lines = [line.strip() for line in lines]
1156+ existing_files = filter(os.path.exists, file_list)
1157+
1158+ If the function you need doesn't exist, you need to write it. One way to write
1159+ small functions is to use the ``lambda `` statement. ``lambda `` takes a number
1160+ of parameters and an expression combining these parameters, and creates a small
1161+ function that returns the value of the expression::
1162+
1163+ lowercase = lambda x: x.lower()
1164+
1165+ print_assign = lambda name, value: name + '=' + str(value)
1166+
1167+ adder = lambda x, y: x+y
1168+
1169+ An alternative is to just use the ``def `` statement and define a function in the
1170+ usual way::
1171+
1172+ def lowercase(x):
1173+ return x.lower()
1174+
1175+ def print_assign(name, value):
1176+ return name + '=' + str(value)
1177+
1178+ def adder(x,y):
1179+ return x + y
1180+
1181+ Which alternative is preferable? That's a style question; my usual course is to
1182+ avoid using ``lambda ``.
1183+
1184+ One reason for my preference is that ``lambda `` is quite limited in the
1185+ functions it can define. The result has to be computable as a single
1186+ expression, which means you can't have multiway ``if... elif... else ``
1187+ comparisons or ``try... except `` statements. If you try to do too much in a
1188+ ``lambda `` statement, you'll end up with an overly complicated expression that's
1189+ hard to read. Quick, what's the following code doing?
1190+
1191+ ::
1192+
1193+ import functools
1194+ total = functools.reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
1195+
1196+ You can figure it out, but it takes time to disentangle the expression to figure
1197+ out what's going on. Using a short nested ``def `` statements makes things a
1198+ little bit better::
1199+
1200+ import functools
1201+ def combine (a, b):
1202+ return 0, a[1] + b[1]
1203+
1204+ total = functools.reduce(combine, items)[1]
1205+
1206+ But it would be best of all if I had simply used a ``for `` loop::
1207+
1208+ total = 0
1209+ for a, b in items:
1210+ total += b
1211+
1212+ Or the :func: `sum ` built-in and a generator expression::
1213+
1214+ total = sum(b for a,b in items)
1215+
1216+ Many uses of :func: `functools.reduce ` are clearer when written as ``for `` loops.
1217+
1218+ Fredrik Lundh once suggested the following set of rules for refactoring uses of
1219+ ``lambda ``:
1220+
1221+ 1) Write a lambda function.
1222+ 2) Write a comment explaining what the heck that lambda does.
1223+ 3) Study the comment for a while, and think of a name that captures the essence
1224+ of the comment.
1225+ 4) Convert the lambda to a def statement, using that name.
1226+ 5) Remove the comment.
1227+
1228+ I really like these rules, but you're free to disagree
1229+ about whether this lambda-free style is better.
1230+
1231+
12351232Revision History and Acknowledgements
12361233=====================================
12371234
0 commit comments