Skip to content Skip to sidebar Skip to footer

Append To A Dict Of Lists With A Dict Comprehension

Suppose I have a large list of words. For an example: >>> with open('/usr/share/dict/words') as f: ... words=[word for word in f.read().split('\n') if word] If I want

Solution 1:

No - dict comprehensions are designed to generate non-overlapping keys with each iteration; they don't support aggregation. For this particular use case, a loop is the proper way to accomplish the task efficiently (in linear time).

Solution 2:

I'd use filter:

>>> words = ['abcd', 'abdef', 'eft', 'egg', 'uck', 'ice']
>>> index = {k.lower() : list(filter(lambda x:x[0].lower() == k.lower(),words)) for k in'aeiou'}
>>> index
{'a': ['abcd', 'abdef'], 'i': ['ice'], 'e': ['eft', 'egg'], 'u': ['uck'], 'o': []}

Solution 3:

This is not exactly a dict comprehension, but:

reduce(lambda d, w: d.setdefault(w[0], []).append(w[1]) or d,
       ((w[0].lower(), w) for w in words
        if w[0].lower() in 'aeiou'), {})

Solution 4:

Not answering the question of a dict comprehension, but it might help someone searching this problem. In a reduced example, when filling growing lists on the run into a new dictionary, consider calling a function in a list comprehension, which is, admittedly, nothing better than a loop.

def fill_lists_per_dict_keys(k, v):
    d[k] = (
        v
        if k not in d 
        else d[k] + v
    )

# global d
d = {}
out = [fill_lists_per_dict_keys(i[0], [i[1]]) for i in d2.items()]

The out is only to suppress the None Output of each loop.

If you ever want to use the new dictionary even inside the list comprehension at runtime or if you run into another reason why your dictionary gets overwritten by each loop, check to make it global with global d at the beginning of the script (commented out because not necessary here).

Post a Comment for "Append To A Dict Of Lists With A Dict Comprehension"