Coconut – built-ins – 12

Coj9

Continuo da qui, oggi su built-ins che semplificano il codice, qui.

addpattern
Takes one argument that is a pattern-matching function, and returns a decorator that adds the patterns in the existing function to the new function being decorated, where the existing patterns are checked first, then the new. Equivalent to:

def addpattern(base_func):
    """Decorator to add a new case to 
       a pattern-matching function, 
       where the new case is checked last."""
    
    def pattern_adder(func):
        def add_pattern_func(*args, **kwargs):
            try:
                return base_func(*args, **kwargs)
            except MatchError:
                return func(*args, **kwargs)
        return add_pattern_func
    return pattern_adder

c48

cosa che con Python … ahemmmm, già 😉

prepattern
Takes one argument that is a pattern-matching function, and returns a decorator that adds the patterns in the existing function to the new function being decorated, where the new patterns are checked first, then the existing. Equivalent to:

def prepattern(base_func):
    """Decorator to add a new case to
       a pattern-matching function, 
       where the new case is checked first."""
    def pattern_prepender(func):
        def pre_pattern_func(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except MatchError:
                return base_func(*args, **kwargs)
        return pre_pattern_func
    return pattern_prepender

c49

con Python –come già detto.

reduce
Coconut re-introduces Python 2’s reduce built-in, using the functools.reduce version.
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. For example, reduce((x, y) -> x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the sequence. If the optional initializer is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty. If initializer is not given and sequence contains only one item, the first item is returned.

c50

takewhile
Coconut provides itertools.takewhile as a built-in under the name takewhile.
takewhile(predicate, iterable)
Make an iterator that returns elements from the iterable as long as the predicate is true. Equivalent to:

def takewhile(predicate, iterable):
    # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
    for x in iterable:
        if predicate(x):
            yield x
        else:
            break

L’esempio proposto mi da errore, forse dovuto alla versione 😦

Coconut:
negatives = takewhile(numiter, (x) -> x<0)

Python:
import itertools
negatives = itertools.takewhile(numiter, lambda x: x<0)


dropwhile
Coconut provides itertools.dropwhile as a built-in under the name dropwhile.

dropwhile(predicate, iterable)
Make an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element. Note: the iterator does not produce any output until the predicate first becomes false, so it may have a lengthy start-up time. Equivalent to:

def dropwhile(predicate, iterable):
    # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
    iterable = iter(iterable)
    for x in iterable:
        if not predicate(x):
            yield x
            break
    for x in iterable:
        yield x

Come per il caso precedente ottengo un errore.

Coconut:
positives = dropwhile(numiter, (x) -> x<0)

Python:
import itertools
positives = itertools.dropwhile(numiter, lambda x: x<0)

tee
Coconut provides itertools.tee as a built-in under the name tee.
tee(iterable, n=2)
Return n independent iterators from a single iterable. Equivalent to:

def tee(iterable, n=2):
    it = iter(iterable)
    deques = [collections.deque() for i in range(n)]
    def gen(mydeque):
        while True:
            if not mydeque:             # when the local deque is empty
                newval = next(it)       # fetch a new value and
                for d in deques:        # load it to all the deques
                    d.append(newval)
            yield mydeque.popleft()
    return tuple(gen(d) for d in deques)

Once tee() has made a split, the original iterable should not be used anywhere else; otherwise, the iterable could get advanced without the tee objects being informed.

This itertool may require significant auxiliary storage (depending on how much temporary data needs to be stored). In general, if one iterator uses most or all of the data before another iterator starts, it is faster to use list() instead of tee().

c51

consume
Coconut provides the consume function to efficiently exhaust an iterator and thus perform any lazy evaluation contained within it. consume takes one optional argument, keep_last, that defaults to 0 and specifies how many, if any, items from the end to return as an iterable (None will keep all elements). Equivalent to:

def consume(iterable, keep_last=0):
    """Fully exhaust iterable and return the last keep_last elements."""
    return collections.deque(iterable, maxlen=keep_last) 
                                    # fastest way to exhaust an iterator

In the process of lazily applying operations to iterators, eventually a point is reached where evaluation of the iterator is necessary. To do this efficiently, Coconut provides the consume function, which will fully exhaust the iterator given to it.

c52

count
Coconut provides a modified version of itertools.count that supports in, normal slicing, optimized iterator slicing, count and index sequence methods, repr, and _start and _step attributes as a built-in under the name count.
count(start=0, step=1)
Make an iterator that returns evenly spaced values starting with number start. Often used as an argument to map() to generate consecutive data points. Also, used with zip() to add sequence numbers. Roughly equivalent to:

def count(start=0, step=1):
    # count(10) --> 10 11 12 13 14 ...
    # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
    n = start
    while True:
        yield n
        n += step

c53

Verifica:

c53-1

In Python can’t be done quickly without Coconut’s iterator slicing, which requires many complicated pieces. The necessary definitions in Python can be found in the Coconut header.

map and zip
Coconut’s map and zip objects are enhanced versions of their Python equivalents that support normal slicing, optimized iterator slicing (through __coconut_is_lazy__), reversed, len, repr, and have added attributes which subclasses can make use of to get at the original arguments to the object (map supports _func and _iters attributes and zip supports the _iters attribute).

c54

In Python can’t be done without defining a custom map type.

datamaker
Coconut provides the datamaker function to allow direct access to the base constructor of data types created with the Coconut data statement. This is particularly useful when writing alternative constructors for data types by overwriting __new__. Equivalent to:

def datamaker(data_type):
    """Returns base data constructor of data_type."""
    return super(data_type, data_type).__new__$(data_type)

Coconut:

data trilen(h):
def __new__(cls, a, b):
return (a**2 + b**2)**0.5 |> datamaker(cls)

Python:

import collections
class trilen(collections.namedtuple("trilen", "h")):
    __slots__ = ()
    def __new__(cls, a, b):
        return super(cls, cls).__new__(cls, (a**2 + b**2)**0.5)


recursive

Coconut provides a recursive decorator to perform tail recursion optimization on a function written in a tail-recursive style, where it directly returns all calls to itself. Do not use this decorator on a function not written in a tail-recursive style or the function will likely break.

c55

La REPL visualizza male la riga “raise TypeError("the argument must be an integer >= 0")“.

In Python can’t be done without a long decorator definition. The full definition of the decorator in Python can be found in the Coconut header.

parallel_map
Coconut provides a parallel version of map under the name parallel_map. parallel_map makes use of multiple processes, and is therefore often much faster than map. Use of parallel_map requires concurrent.futures, which exits in the Python 3 standard library, but under Python 2 will require python -m pip install futures to function.
Because parallel_map uses multiple processes for its execution, it is necessary that all of its arguments be pickleable. Only objects defined at the module level, and not lambdas, objects defined inside of a function, or objects defined inside of the interpreter, are pickleable. Furthermore, on Windows, it is necessary that all calls to parallel_map occur inside of an if __name__ == "__main__" guard.

parallel_map(_func, *iterables_)

Equivalent to map(func, *iterables) except func is executed asynchronously and several calls to func may be made concurrently. If a call raises an exception, then that exception will be raised when its value is retrieved from the iterator.

c56

e

c57

MatchError
A MatchError is raised when a destructuring assignment statement fails, and thus MatchError is provided as a built-in for catching those errors. MatchError objects support two attributes, pattern, which is a string describing the failed pattern, and value, which is the object that failed to match that pattern.

:mrgreen:

Posta un commento o usa questo indirizzo per il trackback.

Trackback

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: