Search code examples
pythonlistcapitalization

Python capitalize list of lists of strings


I am trying to capitalize each string in a list in python 3. I am using this code

def capitalize_nested(t):
    res=[]
    for s in t:
        if isinstance(s,list):
            capitalize_nested(s)
        res.append(s.capitalize())
    return res

The code works for a list of strings, but not for a list of lists of strings, e.g. when I run it for t=["asd",["asd"]] I would expect ["Asd",["Asd"]] as output, instead I obtain the following error:

Traceback (most recent call last):                                                                                             
  File "/home/main.py", line 10, in <module>                                                                                   
    print(capitalize_nested(t))                                                                                                
  File "/home/main.py", line 6, in capitalize_nested                                                                           
    res.append(s.capitalize())                                                                                                 
AttributeError: 'list' object has no attribute 'capitalize'

I don't get what the error means. Why does the code treat the elements of the sublist in the recursion as lists instead of strings?


Solution

  • The error is already telling you the problem: you're trying to call capitalize on a list, which is not possible.

    The reason for this: if s is a list, you are calling your function recursively, which is just fine. But after the recursive call returns, you are calling res.append(s.capitalize()), which gives you the error, because s is a list and therefore there is no capitalize() function.

    Better do something like this:

    def capitalize_nested(t):
        res=[]
        for s in t:
            if isinstance(s, list):
                to_append = capitalize_nested(s)
            else:
                to_append = s.capitalize()
            res.append(to_append)
        return res
    

    Example:

    Input: ["asd",["asd"]]

    Outputs: ['Asd', ['Asd']]

    Note: Of course, this is not the most elegant or beautiful solution, but I didn't want to change your code too much and it hopefully explains the problem.