0

i have following python list comprehension and it's hard for me to understand it

set([device for room, devices in home.items() for device in devices['devices'] + device_synonyms])

I need to simplified it using for operator

home = {'Гостиная': {'devices': ['Мак', 'Основной', 'Ночник']}, 'Коридор': {'devices': ['Роутер', 'Вход', 'Шкаф', 'Вешалка']}, 'Спальня': {'devices': ['Ночник']}}

The expected result should be

{'Вход', 'Ночник', 'Шкаф', 'Вешалка', 'Основной', 'Роутер', 'Мак'}
Selcuk
  • 57,004
  • 12
  • 102
  • 110
Alex Nikitin
  • 841
  • 1
  • 10
  • 29
  • 2
    Does this answer your question? [Understanding nested list comprehension](https://stackoverflow.com/questions/8049798/understanding-nested-list-comprehension) – rchome Dec 10 '21 at 06:53
  • Note: there is no need for this to be a list comprehension. You can feed a generator expression to `set`. – Chris Dec 10 '21 at 06:56
  • @Chris you mean something like set((device for room, devices in home.items() for device in devices['devices'] + device_synonyms)) – Alex Nikitin Dec 10 '21 at 06:57
  • Almost. You can elide a set of parentheses. `set(device for room, devices in home.items() for device in devices['devices'] + device_synonyms)` – Chris Dec 10 '21 at 06:59

2 Answers2

2

The exact translation of the listr comprehension to a for loop is given by:

l = []
for room, devices in home.items():
   for device in devices["devices"] + device_synonyms:
       l.append(device)
s = set(l)
print(s)

As pointed out by chris, there is no need to use the intermediate list:

s = set()
for room, devices in home.items():
   for device in devices["devices"] + device_synonyms:
       s.add(device)
print(s)
Jonathan Weine
  • 655
  • 3
  • 11
  • 1
    There's no need for the intermediate `l` list. You can create `s`, then add to it in the loop with `s.add(device)`. – Chris Dec 10 '21 at 06:59
  • That's true chris, thanks for the addition. I wanted to exactly replicate the comprehension line for demonstration purpose. – Jonathan Weine Dec 10 '21 at 07:03
0

You don't use room and you don't have to append device_synonyms multiple times as duplicates will be removed by set() anyway. So the code can be simplified and rewritten as:

result = set(device_synonyms)
for devices in home.values():
    result |= set(devices['devices'])
Selcuk
  • 57,004
  • 12
  • 102
  • 110