Search code examples
pythonlistdictionaryflatten

Flatten dictionary values with list of lists


I have python dictionary that contains key and values. Its values are all inside one list. However, other elements might be inside another list. I want to return only 1D flat list irrespectively of the situation.

Example:

sample_dict1 = 

defaultdict(list,
            {'File1.xlsx': ['Path/NEW/Subpath/File1.xlsx'],
'File2.xlsx': ['Path/NEW/Subpath/File2.xlsx'],
'File3.xlsx': ['Path/NEW/Subpath/File3.xlsx', ['Path/OLD/Subpath/File3.xlsx']],
'File4.xlsx': ['Path/NEW/Subpath/File4.xlsx', ['Path/OLD/Subpath/File4.xlsx'],
               ['Path/changed/Subpath/File4.xlsx']] } )


DESIRED OUTPUT

output = 

defaultdict(list,
            {'File1.xlsx': ['Path/NEW/Subpath/File1.xlsx'],
'File2.xlsx': ['Path/NEW/Subpath/File2.xlsx'],
'File3.xlsx': ['Path/NEW/Subpath/File3.xlsx', 'Path/OLD/Subpath/File3.xlsx'],
'File4.xlsx': ['Path/NEW/Subpath/File4.xlsx', 'Path/OLD/Subpath/File4.xlsx',
               'Path/changed/Subpath/File4.xlsx'] } )



my attempt:


def flatten(xs):
    for x in xs:
        if isinstance(x, str):
            yield x
        elif isinstance(x, Iterable) and not isinstance(x, str):
            yield from flatten(x)

for k, v in sample_dict1.items():
        sample_dict1[k] = list(flatten(k])




From question Flatten list of lists within dictionary values before processing in Pandas


Solution

  • You made two mistakes:

    1. Use flatten(v)instead of flatten(k)
    2. Get your parentheses right: list(flatten(v)) ìnstead of list(flatten(v])
    def flatten(xs):
        for x in xs:
            if isinstance(x, str):
                yield x
            elif isinstance(x, Iterable) and not isinstance(x, str):
                yield from flatten(x)
    
    for k, v in sample_dict1.items():
            sample_dict1[k] = list(flatten(v))