Playing around with various ways of doing a function for someone's add-on for anki flash card stuff.


In [1]:
s = 'examples/animals/mammals'
s.count('/')


Out[1]:
2

In [2]:
def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    output_terms = []
    for term in terms:
        output_terms.append(term)
        yield delimiter.join(output_terms)

In [3]:
for t in foo(s):
    print(t)


examples
examples/animals
examples/animals/mammals

In [4]:
known_good_output = list(foo(s))

In [5]:
# I like this version best.

def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    for i in range(len(terms)):
        yield delimiter.join(terms[:i+1])

assert list(foo(s)) == known_good_output

In [6]:
# This reduces the body to one statement,
# but the duplication of s.split(delimiter) is ugly,
# so I do not like this version.

def foo(s, delimiter='/'):
    yield from (
        delimiter.join(s.split(delimiter)[:i+1])
        for i in range(len(s.split(delimiter)))
    )

assert list(foo(s)) == known_good_output

In [7]:
# Using terms is less ugly.

def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    yield from (
        delimiter.join(terms[:i+1])
        for i in range(len(terms))
    )

assert list(foo(s)) == known_good_output

In [8]:
# Strictly speaking, this is a regular function
# that returns a generator expression.
# The duplication of s.split(delimiter) is ugly.

def foo(s, delimiter='/'):
    return (
        delimiter.join(s.split(delimiter)[:i+1])
        for i in range(len(s.split(delimiter)))
    )


assert list(foo(s)) == known_good_output

In [9]:
def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    return (delimiter.join(terms[:i+1])
        for i in range(len(terms)))

assert list(foo(s)) == known_good_output

In [10]:
from itertools import accumulate

In [11]:
# Now for a functional approach.

def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    for x in accumulate(terms, str.__add__):
        yield x

list(foo(s))


Out[11]:
['examples', 'examplesanimals', 'examplesanimalsmammals']

In [12]:
def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    for x in accumulate(terms, lambda x, y: delimiter.join((x, y))):
        yield x
    
assert list(foo(s)) == known_good_output

In [13]:
def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    yield from (
        x
        for x in accumulate(terms, lambda x, y: delimiter.join((x, y)))
    )
    
assert list(foo(s)) == known_good_output

In [14]:
def foo(s, delimiter='/'):
    terms = s.split(delimiter)
    yield from accumulate(terms, lambda x, y: delimiter.join((x, y)))
    
assert list(foo(s)) == known_good_output

In [15]:
def foo(s, delimiter='/'):
    yield from accumulate(
        s.split(delimiter),
        lambda x, y: delimiter.join((x, y))
    )
    
assert list(foo(s)) == known_good_output

In [16]:
def foo(s, delimiter='/'):
    return accumulate(
        s.split(delimiter),
        lambda x, y: delimiter.join((x, y))
    )
    
assert list(foo(s)) == known_good_output

In [17]:
def foo(s, delimiter='/'):
    return accumulate(
        s.split(delimiter),
        lambda x, y: x + delimiter + y
    )
    
assert list(foo(s)) == known_good_output