Author: Benjamin Peterson <[email protected]>
Branch:
Changeset: r47969:da18a97b974d
Date: 2011-10-12 11:22 -0400
http://bitbucket.org/pypy/pypy/changeset/da18a97b974d/
Log: merge heads
diff --git a/pypy/module/__builtin__/__init__.py
b/pypy/module/__builtin__/__init__.py
--- a/pypy/module/__builtin__/__init__.py
+++ b/pypy/module/__builtin__/__init__.py
@@ -21,6 +21,8 @@
'all' : 'app_functional.all',
'sum' : 'app_functional.sum',
'map' : 'app_functional.map',
+ 'reduce' : 'app_functional.reduce',
+ 'filter' : 'app_functional.filter',
'vars' : 'app_inspect.vars',
'dir' : 'app_inspect.dir',
@@ -88,9 +90,7 @@
'min' : 'functional.min',
'max' : 'functional.max',
'zip' : 'functional.zip',
- 'reduce' : 'functional.reduce',
'reversed' : 'functional.reversed',
- 'filter' : 'functional.filter',
'super' : 'descriptor.W_Super',
'staticmethod' : 'descriptor.StaticMethod',
'classmethod' : 'descriptor.ClassMethod',
diff --git a/pypy/module/__builtin__/app_functional.py
b/pypy/module/__builtin__/app_functional.py
--- a/pypy/module/__builtin__/app_functional.py
+++ b/pypy/module/__builtin__/app_functional.py
@@ -98,3 +98,68 @@
result.append(func(*args))
else:
return result
+
+sentinel = object()
+
+def reduce(func, sequence, initial=sentinel):
+ """reduce(function, sequence[, initial]) -> value
+
+Apply a function of two arguments cumulatively to the items of a sequence,
+from left to right, so as to reduce the sequence to a single value.
+For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
+((((1+2)+3)+4)+5). If initial is present, it is placed before the items
+of the sequence in the calculation, and serves as a default when the
+sequence is empty."""
+ iterator = iter(sequence)
+ if initial is sentinel:
+ try:
+ initial = next(iterator)
+ except StopIteration:
+ raise TypeError("reduce() of empty sequence with no initial value")
+ result = initial
+ for item in iterator:
+ result = func(result, item)
+ return result
+
+def filter(func, seq):
+ """filter(function or None, sequence) -> list, tuple, or string
+
+Return those items of sequence for which function(item) is true. If
+function is None, return the items that are true. If sequence is a tuple
+or string, return the same type, else return a list."""
+ if func is None:
+ func = bool
+ if isinstance(seq, str):
+ return _filter_string(func, seq, str)
+ elif isinstance(seq, unicode):
+ return _filter_string(func, seq, unicode)
+ elif isinstance(seq, tuple):
+ return _filter_tuple(func, seq)
+ result = []
+ for item in seq:
+ if func(item):
+ result.append(item)
+ return result
+
+def _filter_string(func, string, str_type):
+ if func is bool and type(string) is str_type:
+ return string
+ result = []
+ for i in range(len(string)):
+ # You must call __getitem__ on the strings, simply iterating doesn't
+ # work :/
+ item = string[i]
+ if func(item):
+ if not isinstance(item, str_type):
+ raise TypeError("__getitem__ returned a non-string type")
+ result.append(item)
+ return str_type().join(result)
+
+def _filter_tuple(func, seq):
+ result = []
+ for i in range(len(seq)):
+ # Again, must call __getitem__, at least there are tests.
+ item = seq[i]
+ if func(item):
+ result.append(item)
+ return tuple(result)
\ No newline at end of file
diff --git a/pypy/module/__builtin__/functional.py
b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -222,90 +222,6 @@
return space.newlist(result_w)
result_w.append(space.newtuple(items_w))
-def reduce(space, w_func, w_sequence, w_initial=NoneNotWrapped):
- """ Apply function of two arguments cumulatively to the items of sequence,
- from left to right, so as to reduce the sequence to a single value.
- Optionally begin with an initial value.
- """
- w_iter = space.iter(w_sequence)
- if w_initial is None:
- try:
- w_initial = space.next(w_iter)
- except OperationError, e:
- if e.match(space, space.w_StopIteration):
- msg = "reduce() of empty sequence with no initial value"
- raise OperationError(space.w_TypeError, space.wrap(msg))
- raise
- w_result = w_initial
- while True:
- try:
- w_next = space.next(w_iter)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break
- w_result = space.call_function(w_func, w_result, w_next)
- return w_result
-
-def filter(space, w_func, w_seq):
- """construct a list of those elements of collection for which function
- is True. If function is None, then return the items in the sequence
- which are True.
- """
- if space.is_true(space.isinstance(w_seq, space.w_str)):
- return _filter_string(space, w_func, w_seq, space.w_str)
- if space.is_true(space.isinstance(w_seq, space.w_unicode)):
- return _filter_string(space, w_func, w_seq, space.w_unicode)
- if space.is_true(space.isinstance(w_seq, space.w_tuple)):
- return _filter_tuple(space, w_func, w_seq)
- w_iter = space.iter(w_seq)
- result_w = []
- none_func = space.is_w(w_func, space.w_None)
- while True:
- try:
- w_next = space.next(w_iter)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break
- if none_func:
- w_keep = w_next
- else:
- w_keep = space.call_function(w_func, w_next)
- if space.is_true(w_keep):
- result_w.append(w_next)
- return space.newlist(result_w)
-
-def _filter_tuple(space, w_func, w_tuple):
- none_func = space.is_w(w_func, space.w_None)
- length = space.len_w(w_tuple)
- result_w = []
- for i in range(length):
- w_item = space.getitem(w_tuple, space.wrap(i))
- if none_func:
- w_keep = w_item
- else:
- w_keep = space.call_function(w_func, w_item)
- if space.is_true(w_keep):
- result_w.append(w_item)
- return space.newtuple(result_w)
-
-def _filter_string(space, w_func, w_string, w_str_type):
- none_func = space.is_w(w_func, space.w_None)
- if none_func and space.is_w(space.type(w_string), w_str_type):
- return w_string
- length = space.len_w(w_string)
- result_w = []
- for i in range(length):
- w_item = space.getitem(w_string, space.wrap(i))
- if none_func or space.is_true(space.call_function(w_func, w_item)):
- if not space.is_true(space.isinstance(w_item, w_str_type)):
- msg = "__getitem__ returned a non-string type"
- raise OperationError(space.w_TypeError, space.wrap(msg))
- result_w.append(w_item)
- w_empty = space.call_function(w_str_type)
- return space.call_method(w_empty, "join", space.newlist(result_w))
-
class W_Enumerate(Wrappable):
def __init__(self, w_iter, w_start):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit