'Randomly selecting values from a dictionary and assigning them to a new dictionary
I have a huge list of file paths that I'm trying to organize for a project. I have sorted these file paths into three categories (colors red, green, and blue) and put them into a dictionary. Now I want to randomly select 9 of these file paths (3 from each category) and sort them into a secondary, smaller dictionary. This is the code I have used so far to select the file paths and I've printed them just to check over the output.
counter = 0
while counter < 3:
files = [random.choice(i) for i in colors.values()]
counter += 1
print(files)
From this, I get 3 lists each one containing one of each category. What I need to do now is sort them into a new dictionary:
newDict = {blue1: [],
red1: [],
green1: [],
blue2: [],
red2: [],
green2: [],
blue3: [],
red3: [],
green3: []}
...so that there is one file per key and the file is in the relevant category still. Any advice on how I might be able to do this? Thanks in advance!
Solution 1:[1]
First I'd like to convert:
counter = 0
while counter < 3:
files = [random.choice(i) for i in colors.values()]
counter += 1
print(files)
to:
for _ in range(3):
files = [random.choice(i) for i in colors.values()]
print(files)
or even to:
files = [random.choices(files, k=3) for files in colors.values()]
print(files)
Now you want to store them back, first thing is to remember the colors:
files = [(color, random.choices(files, k=3)) for color, files in colors.items()]
print(files)
Now you can go imperatively:
final_dict = {}
for color, three_files in files:
for i, file in enumerate(three_files, start=1):
final_dict[f"{color}{i}"] = file
Or merge the two steps, no needs for a files temporary name:
final_dict = {}
for color, files in colors.items():
for i, file in enumerate(random.choices(files, k=3), start=1):
final_dict[f"{color}{i}"] = file
But while we're at it we can also do it using a dictionary comprehension:
final_dict = {
f"{color}{i}": file
for color, files in colors.items()
for i, file in enumerate(random.choices(files, k=3), start=1)
}
Solution 2:[2]
EDITED:
This should work, and avoid repetitions. I'm checking if there are enough new files left for each color, if not the selection stops:
colors = {'red': ['file_00', 'file_01', 'file_02', 'file_05'],
'blue': ['file_06', 'file_08', 'file_09', 'file_10'],
'green': ['file_14', 'file_15']}
newDict = {}
for i in range(3):
# check if there are still file names for each color
if any(len(lst) == 0 for lst in colors.values()):
print('Not enough files left!')
break
for color, file_names_list in colors.items():
selected_file = random.choice(file_names_list)
newDict[f'{color}_{i}'] = selected_file
# removing the selected file from the list, so you won't select it again
file_names_list.remove(selected_file)
# just printing the result
for k, v in newDict.items():
print(k, ":", v)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Julien Palard |
| Solution 2 |
