0

How to convert the following code into a nested comprehensions?

new_dict = {'Accounts': 'lbl1', 'Inventory': 'lbl2', 'Manufacture': 'lbl3', 'PayRoll': 'lbl4', 'kannagu': 'lbl1', 'Saragu': 'lbl2', 'Thayarippu': 'lbl3', 'Sambalam': 'lbl4', 'F1': 'lbl1', 'F2': 'lbl2', 'F3': 'lbl3', 'F4': 'lbl4'}

dict_keys = {'name': {'lbl1': 'label1', 'lbl2': 'label2', 'lbl3': 'label3', 'lbl4': 'label4'}, 'item3': {'lbl1': 'F1', 'lbl2': 'F2', 'lbl3': 'F3', 'lbl4': 'F4'}, 'item2': {'lbl1': 'kannagu', 'lbl2': 'Saragu', 'lbl3': 'Thayarippu', 'lbl4': 'Sambalam'}, 'item1': {'lbl1': 'Accounts', 'lbl2': 'Inventory', 'lbl3': 'Manufacture', 'lbl4': 'PayRoll'}, 'printitem': {'lbl1': 'You clicked label1', 'lbl2': 'You clicked label2', 'lbl3': 'You clicked label3', 'lbl4': 'You clicked label4'}}

for key,val in new_dict.items():
        if key == Accounts:
            for k, v in dict_key['printitem'].items():
                if k == val :
                    print(v)
tckraomuqnt
  • 470
  • 4
  • 17
  • 1
    You probably shouldn't. Nested comprehensions are unreadable. They might look cool as you write them but you'll curse everything when you get to fixing issues a year later. – NotAName May 16 '22 at 00:30

3 Answers3

4

Dictionary comprehensions are useful for creating a dictionaries compactly. They need to result in a new dictionary, and they shouldn't have side effects like printing values. This code doesn't create a dictionary, so they're not suitable here.

You actually don't need either of the loops. Both of them are just looking up a key in a dictionary, which can be done with a simple d[key] or d.get(key) lookup. You can simplify this code to:

if val := new_dict.get(sending_button.text()):
    if v := dict_key['printitem'].get(val):
        print(v)

If you're not using Python 3.8 then you can use this longer version without the := walrus operator:

val = new_dict.get(sending_button.text())
if val:
    v = dict_key['printitem'].get(val)
    if v:
        print(v)
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Hey, look, it's the walrus operator! It makes me so happy to see non-contrived use cases where that operator actually makes code *more* readable. – Silvio Mayolo May 16 '22 at 00:40
  • why You use if Val: and If v: what's the basis behind this? , the following things also get the same result : val = new_dict.get(sending_button.text()) v = dict_key['printitem'].get(val) print(v) @Jhon Kugelman – tckraomuqnt May 16 '22 at 00:56
  • I did that to match the behavior of your code, which only prints something if the keys are actually present. If they're not, it doesn't print anything. If you always expect the keys to be there then yeah, you can drop the `if` statements. – John Kugelman May 16 '22 at 03:49
2

If you want v to be in separated nested list per for k, v

[[v for k, v in dict_key['printitem'].items() if k == val] for key, val in new_dict.items() if key == sending_button.text()]

If you want v to be stored in one large list

[v for key, val in new_dict.items() if key == sending_button.text() for k, v in dict_key['printitem'].items() if k == val]
tax evader
  • 2,082
  • 1
  • 7
  • 9
2

Dictionary comprehensions produce dictionaries, as the name implies. Your code does not produce anything. In fact, it only carries side effects (namely, printing to the console), which should generally be avoided inside of comprehensions.

So the answer is: don't do it.

If you think you still need comprehensions to do this, then my answer is: go to the top of this post and read it again.

Still here? Alright, here's how you force Python to print inside of a comprehension. I cannot stress this enough: This is not good Python code; if I saw this in code review, I'd reject it immediately for multiple reasons.

{ k: print(v) for key, val in new_dict.items() if key == sending_button.text() for k, v in dict_key['printitem'].items() if k == val }

Here are all of the reasons you should not do this.

  • It carries side effects inside a comprehension
  • It looks like it produces a dictionary, but that's not the real point of the line; the dictionary is silently discarded
  • It's a really long single statement of code.
  • It's written backwards. You have to read the whole line almost right-to-left to figure out what's going on.

In summary: Do not do this

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116