19

In Python 3 I have a program coded as below. It basically takes an input from a user and checks it against a dictionary (EXCHANGE_DATA) and outputs a list of information.

from shares import EXCHANGE_DATA
portfolio_str=input("Please list portfolio: ")
portfolio_str= portfolio_str.replace(' ','')
portfolio_str= portfolio_str.upper()
portfolio_list= portfolio_str.split(',')
print()
print('{:<6} {:<20} {:>8}'.format('Code', 'Name', 'Price'))
EXCHANGE_DATA = {code:(share_name,share_value) for code, share_name, share_value in EXCHANGE_DATA}
try:
     for code in portfolio_list:
              share_name, share_value = EXCHANGE_DATA[code]
              print('{:<6} {:<20} {:>8.2f}'.format(code, share_name, share_value))  
except KeyError:
     pass

Example input: GPG,HNZ,DIL,FRE

The output is as follows:

Please list portfolio: GPG,HNZ,DIL,FRE

Code  Name                   Price
GPG   Guinnesspeat            2.32
HNZ   Heartland Nz            3.85
DIL   Diligent                5.30
FRE   Freightway              6.71

But if I have an input like:

AIR,HNZ,AAX,DIL,AZX

where the terms AAX,AZX do not exist in the dictionary (EXCHANGE_DATA) but the terms AIR,HNZ,DIL do. The program obviously would throw a KeyError exception but I have neutralized this with pass. The problem is after the pass code has been executed the program exits and I need it to continue on and execute the for loop on DIL. How do I do this?

jevans
  • 399
  • 1
  • 3
  • 11

2 Answers2

36

Why not:

 for code in portfolio_list:
     try:
         share_name, share_value = EXCHANGE_DATA[code]
         print('{:<6} {:<20} {:>8.2f}'.format(code, share_name, share_value)   
     except KeyError:
         continue

OR check dict.get method:

 for code in portfolio_list:
     res = EXCHANGE_DATA.get(code, None)
     if res:
         print('{:<6} {:<20} {:>8.2f}'.format(code, *res)   

And as @RedBaron mentioned:

 for code in portfolio_list:
     if code in EXCHANGE_DATA:
         print('{:<6} {:<20} {:>8.2f}'.format(code, *EXCHANGE_DATA[code])   
Artsiom Rudzenka
  • 27,895
  • 4
  • 34
  • 52
  • 1
    You can also be rid of try except block by using something like `if code in EXCHANGE_DATA: #something else: continue` – RedBaron Mar 27 '13 at 08:04
  • @ArtsiomRudzenka I want to pass a specific key error `KeyError: 'Retail Store'` either I am getting syntax error if doing this ` except KeyError: 'Retail Store': pass ` or Indentation error if doing this ` except KeyError: 'Retail Store' pass` What am I doing wrong? –  Jul 04 '16 at 11:06
  • @ranadan i guess you need to do something like: except KeyError as exc: if 'Retail Store' in exc.message: pass else: raise exc You can find my skype in profile so i would able to help you with more examples – Artsiom Rudzenka Jul 04 '16 at 12:37
  • don't you have to use "pass" instead of "continue" as continue goes to next iteration – haneulkim Jul 28 '19 at 19:10
5

catch the exception in the loop

for code in portfolio_list:
    try:
        share_name, share_value = EXCHANGE_DATA[code]
        print('{:<6} {:<20} {:>8.2f}'.format(code, share_name, share_value)   
    except KeyError:
        pass

Edit: The more pythonic way would be to test if the dict has the element first

for code in portfolio_list:
    if code in EXCHANGE_DATA:
        share_name, share_value = EXCHANGE_DATA[code]
        print('{:<6} {:<20} {:>8.2f}'.format(code, share_name, share_value)   
xuanji
  • 5,007
  • 2
  • 26
  • 35
  • It's definitely not the more pythonic way, many pythonistas would prefer the first since it's better to ask for forgiveness than permission. http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#eafp-vs-lbyl – jamylak Mar 27 '13 at 08:22
  • @RedBaron I disagree, also that case is slightly different, anyway the word pythonic has no clear definition. – jamylak Mar 27 '13 at 08:56
  • it's only "better to ask for forgiveness than permission" to avoid being too restrictive on what you accept, but in this case a code in ... test is not too restrictive and clearer – xuanji Mar 27 '13 at 09:00
  • Many ways to do the same thing, To each his own :) – RedBaron Mar 27 '13 at 09:01