简体   繁体   中英

Pythonic way to create a dictionary of lists (dict comprehension)

I have the following list:

files = ['AAA_1', 'BBB_2', 'CCC_1', 'AAA_2', 'BBB_4']

And I have the following dict:

dict = {
     'AAA' : [],
     'BBB': [],
     'CCC' : []
}

My expected output is:

dict = {
     'AAA' : ['AAA_1', 'AAA_2'],
     'BBB': ['BBB_2', 'BBB_4'],
     'CCC' : ['CCC_1']
}

I was able to achieve this using:

for file in files:
    if file.startswith(file[:-2]):
        dict[file[:-2]].append(file)

If I use:

dict = {file[:-2]: [file] for file in files if file.startswith(file[:-2])}

I got:

{'AAA': ['AAA_2'], 'BBB': ['BBB_4'], 'CCC': ['CCC_1']}

My doubt is: How can I append values in a dictionary of lists using dict comprehension?

I would not recommend using a dictionary comprehension, as a simple for-loop structure is much more readable. But if you must have one, here you go:

sorted_files = {f[:-2] : [file for file in files if file.startswith(f[:-2])] for f in files}

Also, I do not recommend using Python keywords as variable names. It is bad practice, and sometimes you may confuse the program.

Output:

{'AAA': ['AAA_1', 'AAA_2'], 'BBB': ['BBB_2', 'BBB_4'], 'CCC': ['CCC_1']}

你可以用这样的两个嵌套推导来做到这一点:

dict = {key: [file for file in files if file[:-2] == key] for key in dict}

If you want to do this purely with comprehensions, you need an inner list comprehension that builds the entire list for a given prefix, and you probably want another comprehension to build the set of prefixes/keys (although this isn't strictly necessary since you can regenerate each entry multiple times and it'll just overwrite itself):

>>> files = ['AAA_1', 'BBB_2', 'CCC_1', 'AAA_2', 'BBB_4']
>>> {k: [f for f in files if f.startswith(k)] for k in {f[:3] for f in files}}
{'BBB': ['BBB_2', 'BBB_4'], 'AAA': ['AAA_1', 'AAA_2'], 'CCC': ['CCC_1']}

Note that in addition to being a little less legible, it's less efficient because you need to iterate over files in its entirety for each entry. Using a loop that iterates over files once is the method I'd use.

All you need is to use nested comprehension:

dict_ = {
    file_group[:-2]: [file for file in files if file.startswith(file_group[:-2])] for file_group in files}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM