Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaving values blank if not passed in str.format

Tags:

I've run into a fairly simple issue that I can't come up with an elegant solution for.

I'm creating a string using str.format in a function that is passed in a dict of substitutions to use for the format. I want to create the string and format it with the values if they're passed and leave them blank otherwise.

Ex

kwargs = {"name": "mark"} "My name is {name} and I'm really {adjective}.".format(**kwargs) 

should return

"My name is mark and I'm really ." 

instead of throwing a KeyError (Which is what would happen if we don't do anything).

Embarrassingly, I can't even come up with an inelegant solution for this problem. I guess I could solve this by just not using str.format, but I'd rather use the built-in (which mostly does what I want) if possible.

Note: I don't know in advance what keys will be used. I'm trying to fail gracefully if someone includes a key but doesn't put it in the kwargs dict. If I knew with 100% accuracy what keys would be looked up, I'd just populate all of them and be done with it.

like image 938
marky1991 Avatar asked Nov 05 '13 21:11

marky1991


People also ask

What does {: 3f mean in Python?

"f" stands for floating point. The integer (here 3) represents the number of decimals after the point. "%. 3f" will print a real number with 3 figures after the point. – Kefeng91.

What is str format () in Python?

The format() method formats the specified value(s) and insert them inside the string's placeholder. The placeholder is defined using curly brackets: {}. Read more about the placeholders in the Placeholder section below. The format() method returns the formatted string.

Which formatting method's in python3 allows multiple substitutions and value formatting?

Python's str. format() method of the string class allows you to do variable substitutions and value formatting. This lets you concatenate elements together within a string through positional formatting.


2 Answers

You can follow the recommendation in PEP 3101 and use a subclass Formatter:

import string  class BlankFormatter(string.Formatter):     def __init__(self, default=''):         self.default=default      def get_value(self, key, args, kwds):         if isinstance(key, str):             return kwds.get(key, self.default)         else:             return string.Formatter.get_value(key, args, kwds)  kwargs = {"name": "mark", "adj": "mad"}      fmt=BlankFormatter() print fmt.format("My name is {name} and I'm really {adj}.", **kwargs) # My name is mark and I'm really mad. print fmt.format("My name is {name} and I'm really {adjective}.", **kwargs) # My name is mark and I'm really .   

As of Python 3.2, you can use .format_map as an alternative:

class Default(dict):     def __missing__(self, key):         return '{'+key+'}'  kwargs = {"name": "mark"}  print("My name is {name} and I'm really {adjective}.".format_map(Default(kwargs))) 

which prints:

My name is mark and I'm really {adjective}. 
like image 182
dawg Avatar answered Nov 07 '22 22:11

dawg


Here is one option which uses collections.defaultdict:

>>> from collections import defaultdict >>> kwargs = {"name": "mark"} >>> template = "My name is {0[name]} and I'm really {0[adjective]}." >>> template.format(defaultdict(str, kwargs)) "My name is mark and I'm really ." 

Note that we aren't using ** to unpack the dictionary into keyword arguments anymore, and the format specifier uses {0[name]} and {0[adjective]}, which indicates that we should perform a key lookup on the first argument to format() using "name" and "adjective" respectively. By using defaultdict a missing key will result in an empty string instead of raising a KeyError.

like image 43
Andrew Clark Avatar answered Nov 07 '22 21:11

Andrew Clark