0
votes
\$\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\$
2
  • \$\begingroup\$ What's the expected output for this example? Are you sure that it works? \$\endgroup\$ Commented Mar 31, 2016 at 21:47
  • \$\begingroup\$ edited the question @200_success \$\endgroup\$ Commented Mar 31, 2016 at 21:49

1 Answer 1

2
votes
\$\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\$
3
  • \$\begingroup\$ thank you for your suggestion, mainly those dictionaries should and will always have the same length. @200_success \$\endgroup\$ Commented Mar 31, 2016 at 22:06
  • 1
    \$\begingroup\$ You still can't count on them to have any predictable iteration order. \$\endgroup\$ Commented Mar 31, 2016 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\$ Commented Apr 1, 2016 at 16:11

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.