0
\$\begingroup\$

I have two dictionaries that I need the keys to match and if they match i will get the value of the first dictionary and then get the value of 2nd dictionary and build a new dictionary out of those.

dic1 = {u'ShutterHours': 732, u'ShieldHours': 732, u'MaskHours': 28, u'TargetHours': 790, u'GndRingHours': 25}
dic2 = {u'ShutterHours': u'Shutter Hours', u'ShieldHours': u'Shield Hours', u'MaskHours': u'Mask Hours', u'TargetHours': u'Target Hours', u'GndRingHours': u'Ground Ring Hours'}

This is my code so far:

final = {}
for k,k2 in zip(dic1,dic2):
    if k == k2:
        final[dic2[k]] = dic1[k]

Expected output:

{u'Ground Ring Hours': 25, u'Shutter Hours': 732, u'Shield Hours': 732, u'Mask Hours': 28, u'Target Hours': 790}

This works fine but I'm a bit skeptical if this is the best and Pythonic way to do this.

\$\endgroup\$
  • \$\begingroup\$ What's the expected output for this example? Are you sure that it works? \$\endgroup\$ – 200_success Mar 31 '16 at 21:47
  • \$\begingroup\$ edited the question @200_success \$\endgroup\$ – wasp8898 Mar 31 '16 at 21:49
2
\$\begingroup\$

This mechanism is so fragile that I can't tell for sure what it is supposed to do. The main issue is that you can't reliably predict the order in which the keys of a dictionary will be enumerated. For example, this seems to work as you intend:

>>> dic1 = {u'ShutterHours': 732, u'ShieldHours': 732, u'MaskHours': 28, u'TargetHours': 790, u'GndRingHours': 25}
>>> dic2 = {u'ShutterHours': u'Shutter Hours', u'ShieldHours': u'Shield Hours', u'MaskHours': u'Mask Hours', u'TargetHours': u'Target Hours', u'GndRingHours': u'Ground Ring Hours'}
>>> list(zip(dic1, dic2))
[('ShutterHours', 'ShutterHours'), ('ShieldHours', 'ShieldHours'), ('GndRingHours', 'GndRingHours'), ('MaskHours', 'MaskHours'), ('TargetHours', 'TargetHours')]

However, if you insert one entry into dic2, the whole thing might fall apart:

>>> …
>>> dic2[''] = 'empty string'
>>> list(zip(dic1, dic2))
[('ShutterHours', 'ShutterHours'), ('ShieldHours', ''), ('GndRingHours', 'GndRingHours'), ('MaskHours', 'ShieldHours'), ('TargetHours', 'MaskHours')]

What you probably want is a dict comprehension.

final = {dic2[k]: v for k, v in dic1.items()}

Better variable names would make the code easier to understand as well (e.g. labels instead of dic2).

\$\endgroup\$
  • \$\begingroup\$ thank you for your suggestion, mainly those dictionaries should and will always have the same length. @200_success \$\endgroup\$ – wasp8898 Mar 31 '16 at 22:06
  • 1
    \$\begingroup\$ You still can't count on them to have any predictable iteration order. \$\endgroup\$ – 200_success Mar 31 '16 at 22:06
  • \$\begingroup\$ You should at least use final = {dic2[k]: v for k, v in dic1.items() if k in dic2} for the cases where a key is in dic1 and not in dic2. \$\endgroup\$ – Cilyan Apr 1 '16 at 16:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.