'function that transforms a list of strings using a list of tuples?

I want to make a function that takes in a list of strings and a list of tuples as inputs. It then reacts to keywords in the list of tuples to modify the list of strings. the function should look like transform('stringlist','tuplelist')

For example, suppose we use the stringlist is ['cloud', 'terra']

here is how the different tuples will affect the string list:

(‘uppercase’, n) will change every nth letter in the list of strings to uppercase. ex. transform(['cloud','terra'], [(‘uppercase’, 2)]) will return ['cLoUd','tErRa']

(‘first’,n) will split the list so only the first n letters are present. ex. transform(['cloud','terra'], [(‘first’,3)]) will return ['clo','ter']

(‘last’,n) will split the list so only the last n letters are present. ex. transform(['cloud','terra'], [(‘last’, 3)]) will return ['oud','rra']

(‘insert’, n, x) will insert a string in the list’s nth index. ex. transform(['cloud','terra'], [(‘insert’, 1, ‘zidane’)]) will return ['cloud','zidane','terra']

('delete', n) will delete the nth index in the list. ex. transform(['cloud','terra'], [(‘delete’, 0)]) will return [‘terra’]

('length',n). If the length of a string is greater than n, then str(len(examplestr)) will be placed in the middle of examplestr. If examplestr cannot be split in half evenly, then it will use the position of len(examplestr)/2 rounded down the nearest whole number. ex. transform(['cloud','terra'], [(‘length’, 2)]) will return [‘cl5oud’,’te5rra’]

if a list is comprised of multiple tuples, it should look like:

transform(['cloud','terra'],[('last',2),('delete',0)]) 

which outputs ['ra']

What I'm Trying

for i in range(len(tuplelist)):
    if 'last' in tuplelist[i]:
        output = [j[((tuplelist[i])[1]-1):] for j in stringlist]
output

this excerpt takes in:

stringlist = ['cloud','terra']
tuplelist = [('last',3)]

as inputs and outputs ['oud', 'rra']. This is mainly a proof of concept and I wanted to see if it would be possible to modify the string using only if statements and for loops. However, I would like to see if this function could be done using lambda and list comprehension without the use of imports.



Solution 1:[1]

I think what you need is something like this. See comments for details.

from functools import reduce

class Transformer:
    # define some transformer functions.
    # lambda is a short cut, but better to write independent functions.
    uppercase = lambda str_list, n: [str.replace(d, d[n], d[n].upper(), 1) for d in str_list]
    first = lambda str_list, n: [d[:n] for d in str_list]
    last = lambda str_list, n: [d[-n:] for d in str_list]
    insert = lambda str_list, n, x: str_list.insert(n, x)

    # Add  more functions as you need them

    # define a function to transform a list of strings using a function and its args
    @staticmethod
    def _transform_exec(str_list, transformer):
        func, args = transformer[0], transformer[1]
        return func(str_list, *args)

    @staticmethod
    def transform(str_list, *transformers):
        # Collect the string list and function list
        transformer_list = []
        for transformer in transformers:
            # for each transformer str, find the function delegate and its args
            _transformer = getattr(Transformer, transformer[0])
            transformer_list.append([_transformer, transformer[1:]])
        
        # run a pipeline of transformers
        return reduce(Transformer._transform_exec, transformer_list, str_list)


if __name__ == '__main__':
    res = Transformer.transform(['cloud', 'terra'], ('uppercase', 1), ('first', 3), ('last', 1))
    print(res)

This produces an output

['o', 'r']

The approach is only to create a pipeline of different functions using the reduce. This is only an example to demonstrate the possible appraoch. You will have to work to make it robust

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kris