Home > Software design >  Replacing a variable in a list with the result of a regex search in a Python function
Replacing a variable in a list with the result of a regex search in a Python function

Time:06-07

I have three lists lst_a to lst_c. I would like to write a function that takes each item from the lists, performs a regex search according to lst_b with search group position according to lst_c and replaces the variables in lst_a with the search results.

This is my code:

import re

var_1 = var_2 = var_3 = "replace_me"

lst_a = [
var_1,
var_2,
var_3,
]

lst_b = [
'(foo)(bar)',
'(foo)(bar)(baz)',
'(foo)(baz)(bar)',
]

lst_c = [1, 2, 3]

def lst_search_n_save(variables, regex, position):
    global lst_a
    global lst_b
    for r in regex:
        try:
            variables = re.search(r, "foobarbaz")
            #variables := re.search(r, "foobarbaz") -> not working
            print(variables)
            print(rf"{variables.group(position)}")
        except (AttributeError, TypeError, IndexError):
            print("error"   "\n")
            variables = "not found"

lst_search_n_save(lst_a, lst_b, lst_c[2])

print(lst_a)

Searching and finding works, but I cannot get the function to save its results into the variables in lst_a. This is what I get instead:

<re.Match object; span=(0, 6), match='foobar'>
error

<re.Match object; span=(0, 9), match='foobarbaz'>
baz
None
error

['replace_me', 'replace_me', 'replace_me']

The expected output for the used positional parameter in my example should be:

print(lst_a)
['not found', 'baz', 'bar']

print(lst_a[1])
baz

CodePudding user response:

First of all, the expected result is not consistent. It would mean that the third regular expression "(foo)(baz)(bar)" would find a match in "foobarbaz", which is not true. So also the third result should be "not found".

Then some remarks on your attempt:

  • As arguments become local variables, you cannot expect the function to change the global list_a by just assigning to the local variable variables. list_a will not change by running this function.

  • To overcome the first issue, it would be more fitting to have the function return the list with the three results, and to not pass an argument for that.

  • Since you want to produce a list, you should not assign a result to variables, but append the results to it, and so build the list you want to return

  • Avoid global statements. They are not needed here.

  • Avoid a hard-coded value in your function like "foobarbaz". Instead pass it as argument to the function, so it becomes more flexible.

  • Not an issue, but although your problem statement speaks of a list_c, your code only ever uses one value from that list. So then it doesn't need to be a list. But I'll leave that part untouched.

  • I would avoid calling a variable variables, which suggests that this variable contains variables... which makes little sense. Let's call it results.

Here is a correction:

import re

def lst_search_n_save(regex, position, s):
    results = []
    for r in regex:
        try:
            match = re.search(r, s)
            result = match.group(position)
        except (AttributeError, TypeError, IndexError):
            result = "not found"
        results.append(result)
    return results

# Example given in question:
lst_b = ['(foo)(bar)', '(foo)(bar)(baz)', '(foo)(baz)(bar)']
lst_c = [1, 2, 3]
lst_a = lst_search_n_save(lst_b, lst_c[2], "foobarbaz")

print(lst_a)  # ['not found', 'baz', 'not found']
  • Related