Search code examples
pythonlist-comprehensionos.path

Join the keys (file paths) of a dictionary to its items (items in that dictionary)


I have a dictionary that looks like this:

import os    
file_names = {'C:\Data\Path1': ['item1.file', 'item2.file'], 
                  'C:\Data\Path2': ['item3.file', 'item4.file']}

I'm trying to use os.path.join to combine the path, and the corresponding items to have a full file path. e.g.

file_paths = {'C:\Data\Path1': ['C:\Data\Path1\item1.file', 'C:\Data\Path1\item2.file'], 
              'C:\Data\Path2': ['C:\Data\Path1\item2.file', 'C:\Data\Path1\item3.file']}

So far, I've tried:

file_paths = {folder: os.path.join(folder, file_names[folder][item])
                               for folder in file_names.keys()
                               for item, _ in enumerate(file_names[folder])}

Rather than having two outputs per dictionary key, I'm getting only one, the last item in the original dictionary key.


Solution

  • I recommend first describing the steps in words so you can think about the solution more clearly. For example, you might write something like this:

    for each key that is a file path
      get the list of files at that path
      join file path with each file name in the list
    

    Now we can translate this into python code:

    for path in file_paths.keys():
        files = file_paths[key]
        file_paths[path] = [path.join(file) for file in files]
    

    Note how this is a for loop split across multiple lines. This is almost always easier to implement than trying to do it all in one line with a comprehension. Once you get this working the way you want, then you can try to turn it into a single line.

    For example, we can use items() to eliminate the first line in the for loop:

    for path, files in file_paths.items():
        file_paths[path] = [path.join(file) for file in files]
    

    Now we can make this into a dict comprehension:

    file_paths = {path: [path.join(file) for file in files] for path, files in file_paths.items()}
    

    With some practice, you can get to where you just figure out this final version from the very beginning, but if you are having trouble with it, then back up and try to make it simpler by breaking the problem into smaller steps.