Question

I have the following Python code (I'm using Python 2.7.X):

my_csv = '{first},{middle},{last}'
print( my_csv.format( first='John', last='Doe' ) )

I get a KeyError exception because 'middle' is not specified (this is expected). However, I want all of those placeholders to be optional. If those named parameters are not specified, I expect the placeholders to be removed. So the string printed above should be:

John,,Doe

Is there built in functionality to make those placeholders optional, or is some more in depth work required? If the latter, if someone could show me the most simple solution I'd appreciate it!

Was it helpful?

Solution

Here is one option:

from collections import defaultdict

my_csv = '{d[first]},{d[middle]},{d[last]}'
print( my_csv.format( d=defaultdict(str, first='John', last='Doe') ) )

OTHER TIPS

"It does{cond} contain the the thing.".format(cond="" if condition else " not")

Thought I'd add this because it's been a feature since the question was asked, the question still pops up early in google results, and this method is built directly into the python syntax (no imports or custom classes required). It's a simple shortcut conditional statement. They're intuitive to read (when kept simple) and it's often helpful that they short-circuit.

Here's another option that uses the string interpolation operator %:

class DataDict(dict):
    def __missing__(self, key):
        return ''

my_csv = '%(first)s,%(middle)s,%(last)s'
print my_csv % DataDict(first='John', last='Doe')  # John,,Doe

Alternatively, if you prefer using the more modern str.format() method, the following would also work, but is less automatic in the sense that you'll have explicitly define every possible placeholder in advance (although you could modify DataDict.placeholders on-the-fly if desired):

class DataDict(dict):
    placeholders = 'first', 'middle', 'last'
    default_value = ''
    def __init__(self, *args, **kwargs):
        self.update(dict.fromkeys(self.placeholders, self.default_value))
        dict.__init__(self, *args, **kwargs)

my_csv = '{first},{middle},{last}'
print(my_csv.format(**DataDict(first='John', last='Doe')))  # John,,Doe

I faced the same problem as yours and decided to create a library to solve this problem: pyformatting.
Here is the solution to your problem with pyformatting:

>>> from pyformatting import defaultformatter
>>> default_format = defaultformatter(str)
>>> my_csv = '{first},{middle},{last}'
>>> default_format(my_csv, first='John', last='Doe')
'John,,Doe'

The only problem is pyformatting doesn't support python 2. pyformatting supports python 3.1+ If i see any feedback on the need for 2.7 support i think i will add that support.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top