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

107 Views Asked by At

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.

2

There are 2 best solutions below

0
Code-Apprentice On BEST ANSWER

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.

0
Tom Karzes On

This should do what you want:

file_paths = {folder: [os.path.join(folder, file) for file in file_list]
              for folder, file_list in file_names.items()}

This is a dictionary comprehension with a nested list comprehension.