Thomas S.
Thomas S.

Reputation: 184

Applying a list of functions to a single dynamic string

I'm creating a small python app that formats a file's name to a set of rules. I'm having problems finding a way of applying a list of general formatting functions to the same string. I want to apply one function, then another, then another.

I've managed to find a way that works, but I feel that it's very clumsy.

Here I have a list of lists that includes one function and a dictionary of the kwargs. (All of these functions have a "text" parameter that is not included in the dictionary).

functions = [
[SRF.change, {'old': '.', 'new': ' '}],
[SRF.surround, {'value': SU.get_year}],
[SRF.remove, {'chars': '[],'}],
[SRF.capitalize_words, {}],
[SRF.remove_including, {'value': 'mp4'}]]

I then pass it into the custom_rename function. It loops over the list of functions and applies it to the "text" variable. As you can see, the variable changes every time func(text, **kwargs) is called.

def custom_rename(text, functions_list):

    # Apply a list of functions to a string
    for func_list in functions_list:
        func = func_list[0]  # Function
        kwargs = func_list[1]  # Dictionary
        try:
            text = func(text, **kwargs)
        except AttributeError:
            pass

    return text

Is there a more elegant way of doing this? I, for example, do not like that I have to know that the function is in position [0] and the dictionary is in [1].

Upvotes: 0

Views: 58

Answers (1)

Aran-Fey
Aran-Fey

Reputation: 43246

Instead of storing [function, arguments] lists, you can use functools.partial to create callables with the arguments already baked in:

from functools import partial

functions = [
    partial(SRF.change, old='.', new=' '),
    partial(SRF.surround, value=SU.get_year),
    partial(SRF.remove, chars='[],'),
    SRF.capitalize_words,
    partial(SRF.remove_including, value='mp4')
]

Now your custom_rename function can be simplified to this:

def custom_rename(text, functions_list):
    # Apply a list of functions to a string
    for func in functions_list:
        try:
            text = func(text)
        except AttributeError:
            pass

    return text

Upvotes: 2

Related Questions