Is there way to do conditional dictionary definitions in python?

Question:

I’m the author of Pythonizer, and I’m trying to convert this code from perl to python:

%entity2char = (
 # Some normal chars that have special meaning in SGML context
 amp  => '&',     # ampersand
 'gt' => '>',     # greater than
 # PUBLIC ISO 8879-1986//ENTITIES Added Latin 1//EN//HTML
 AElig  => chr(198),  # capital AE diphthong (ligature)
 Aacute => chr(193),  # capital A, acute accent
 ( $] > 5.007 ? (
  'OElig;'    => chr(338),
  'diams;'    => chr(9830),
  ) : ())
);

The AI we’re not supposed to talk about here recommended:

entity2char = {'amp': '&', 'gt': '>', 'AElig': chr(198), 'Aacute': chr(193), 
       **{'OElig;': chr(338), 'diams;': chr(9830), } if 5.034 > 5.007 else **{}})

But that gives a syntax error pointing to the if. Any ideas on how to convert this expression from perl to python? It should wind up being one line of code if at all possible (e.g. the code could be nested inside an arbitrary expression and not in a basic assignment statement).

Asked By: snoopyjc

||

Answers:

If you want to conditionally include certain key-value pairs in a dict you’re building, you can use dict unpacking, where the target of the unpacking is either an empty dict or a dict with those key-value pairs, depending on the condition.

For example,

{'a': 1, **({'b': 2, 'c': 3} if x > 3 else {})}

will build a dict that has 'a': 1 as a key-value pair, and also has 'b': 2 and 'c': 3 if the x > 3 condition holds.

Answered By: user2357112
entity2char = {'amp': '&', 'gt': '>', 'AElig': chr(198), 'Aacute': chr(193), 
       **({'OElig;': chr(338), 'diams;': chr(9830), } if 5.034 > 5.007 else {})}

Use **(if_expression) in dictionaries.

Answered By: Mike