Playing around with various ways of doing a function for someone's add-on for [anki](https://en.wikipedia.org/wiki/Anki_(software%29) flash card stuff.
s = 'examples/animals/mammals'
s.count('/')
2
def foo(s, delimiter='/'):
terms = s.split(delimiter)
output_terms = []
for term in terms:
output_terms.append(term)
yield delimiter.join(output_terms)
for t in foo(s):
print(t)
examples examples/animals examples/animals/mammals
known_good_output = list(foo(s))
# 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
# 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
# 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
# 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
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
from itertools import accumulate
# 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))
['examples', 'examplesanimals', 'examplesanimalsmammals']
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
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
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
def foo(s, delimiter='/'):
yield from accumulate(
s.split(delimiter),
lambda x, y: delimiter.join((x, y))
)
assert list(foo(s)) == known_good_output
def foo(s, delimiter='/'):
return accumulate(
s.split(delimiter),
lambda x, y: delimiter.join((x, y))
)
assert list(foo(s)) == known_good_output
def foo(s, delimiter='/'):
return accumulate(
s.split(delimiter),
lambda x, y: x + delimiter + y
)
assert list(foo(s)) == known_good_output