Skip to content

Instantly share code, notes, and snippets.

@Prodge
Created July 26, 2017 08:27
Show Gist options
  • Save Prodge/fad2efe0a4f1431a84891ef6ab074c29 to your computer and use it in GitHub Desktop.
Save Prodge/fad2efe0a4f1431a84891ef6ab074c29 to your computer and use it in GitHub Desktop.
Python 'Thread First', 'Thread Last' and 'Thread As' Functions - no dependencies
def thread_first(value, *forms):
'''
Returns the given value threaded through the given collection of forms as the first argument.
A form is a function or a tuple containing a function as its first element and a list of arguments.
The return value of the previously called function will be threaded in as the first argument to the next function.
Use this to flatten nested function calls.
Example:
>>> def add(a, b):
... return a + b
...
>>> set(add(list((1,2,)), [3]))
set([1, 2, 3])
>>> thread_first(
... (1,2,),
... list,
... (add, [3]),
... set
... )
set([1, 2, 3])
'''
if forms:
front_form = forms[0]
if callable(front_form):
return thread_first(front_form(value), *forms[1:])
return thread_first(front_form[0](value, *front_form[1:]), *forms[1:])
return value
def thread_last(value, *forms):
'''
Returns the given value threaded through the given collection of forms as the last argument.
Refer to docs above.
'''
if forms:
front_form = forms[0]
if callable(front_form):
return thread_last(front_form(value), *forms[1:])
return thread_last(front_form[0](*(list(front_form[1:]) + [value])), *forms[1:])
return value
def thread_as(value, *forms):
'''
Returns the given value threaded through the given collection of forms in the position of the argument defined by a {}.
Example:
>>> join = lambda a,b,c: a+b+c
...
>>> thread_as([2], (join, [1], {}, [3]), set)
set([1, 2, 3])
'''
def replace_placeholder(args):
return map(lambda arg: value if arg == {} else arg, args)
if forms:
front_form = forms[0]
if callable(front_form):
return thread_as(front_form(value), *forms[1:])
return thread_as(front_form[0](*replace_placeholder(front_form[1:])), *forms[1:])
return value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment