Search code examples
pythonregexstringif-statementlambda

How to add an if conditional inside a lambda function to determine what string concatenate to another string?


def weeks_to_days(input_text, nro_days_in_a_week = 7):
    input_text = re.sub(
                r"(\d+)[\s|]*(?:semanas|semana)",
                lambda m: str(int(m[1]) * nro_days_in_a_week) + " dias ",
                input_text)

    return input_text


input_text = "en 1 semana quizas este lista, aunque viendole mejor, creo esta muy oxidada y seguro la podre poner en marcha en 3 semanas"

print(weeks_to_days(input_text))

The problem with this lambda function is that it always puts "dias" in the plural no matter how many.

How do I place this conditional inside the lambda function to determine if it is "dias" in the plural or if it is "dia" in the singular depending on the amount

if   (str(m[1]) != "1"): str(int(m[1]) * nro_days_in_a_week) + " dias "
elif (str(m[1]) == "1"): str(int(m[1]) * nro_days_in_a_week) + " dia "

Taking that string from the example, we should get this output:

"en 7 dias quizas este lista, aunque viendole mejor, creo esta muy oxidada y seguro la podre poner en marcha en 21 dias"

In this case, since they are weeks, they will always remain in the plural, but assuming that the week lasts 1 day as a parameter, then the problem would be there.


Solution

  • You can use

    import re
    def weeks_to_days(input_text, nro_days_in_a_week = 7):
        input_text = re.sub(
                    r"(\d+(?:\.\d+)?)\s*semanas?\b",
                    lambda m: str(int(float(m[1]) * nro_days_in_a_week)) + (" dia" if round(float(m[1]) * nro_days_in_a_week) == 1 else " dias"),
                    input_text)
    
        return input_text
    
    
    input_text = "en 0.142858 semanas quizas este lista, aunque viendole mejor, creo esta muy oxidada y seguro la podre poner en marcha en 3 semanas"
    print(weeks_to_days(input_text))
    

    The regex is now (\d+(?:\.\d+)?)\s*semanas?\b:

    • (\d+(?:\.\d+)?) - Group 1: one or more digits followed with an optional sequence of a . and one or more digits
    • \s* - zero or more whitespaces
    • semanas? - semana and an optional s char
    • \b - a word boundary.

    The lambda m: str(int(float(m[1]) * nro_days_in_a_week)) + (" dia" if round(float(m[1]) * nro_days_in_a_week) == 1 else " dias") replacement now concatenates:

    • str(int(float(m[1]) * nro_days_in_a_week)) - the number of days that is the Group 1 multiplied by the nro_days_in_a_week
    • (" dia" if round(float(m[1]) * nro_days_in_a_week) == 1 else " dias") adds dia if the result of Group 1 value and nro_days_in_a_week multiplication is rounded to 1, else, dias is used.