1

Conditional list appending for a key to a dictionary:

results = {}

for item, data in myDict.items():
  if (key := data['attr']) not in results:
    results[key] = []
  results[key].append(item)

Ideal dictionary comprehension:

results = {key: results[key].append(item) for item, data in myDict.items()}

But obviously if the key hasn't been instantiated as an empty list it won't work.

Also the results[key].append(item) will not work.

Possibly a lambda function?

leopardxpreload
  • 767
  • 5
  • 17
  • @jarmod Doesn't look like the same thing. – user202729 Feb 26 '21 at 01:41
  • @leo Explain what you're trying to do, instead of showing only the code. – user202729 Feb 26 '21 at 01:42
  • Or [Group dictionary key values in python - Stack Overflow](https://stackoverflow.com/questions/18180145/group-dictionary-key-values-in-python)is. – user202729 Feb 26 '21 at 01:44
  • Does this answer your question? [Grouping Python dictionary keys as a list and create a new dictionary with this list as a value](https://stackoverflow.com/questions/15751979/grouping-python-dictionary-keys-as-a-list-and-create-a-new-dictionary-with-this) – user202729 Feb 26 '21 at 01:45

1 Answers1

1

You can't write this as a comprehension: each element of the comprehension is a filtered version of the things you are iterating over. All elements in the comprehension are processed and appended to a single container independently. You are asking to append to different containers depending on the key, so no comprehension.

The simplest approach I can think of instead is to use collections.defaultdict:

from collections import defaultdict

result = defaultdict(list)
for item, data in myDict.items():
    result[data['attr']].append(item)

Now you could cheat the system by creating a function that has some unrelated side-effects and use that to filter the output. In that case, the only real benefit would be to write the already legible for loop in one line. You would want to consume the comprehension without actually storing the results of the function:

from collections import deque, defaultdict

results = defaultdict(list)
deque((results[data['attr']].append(item) for item, data in myDict.items()), maxlen=0)

This trick using collections.deque with maxlen=0 is one of the faster ways to consume an iterator purely for its side-effects.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264