string.format() with optional placeholders

16,639

Solution 1

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') ) )

Solution 2

"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.

Solution 3

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
Share:
16,639

Related videos on Youtube

void.pointer
Author by

void.pointer

Updated on June 04, 2022

Comments

  • void.pointer
    void.pointer almost 2 years

    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!

  • void.pointer
    void.pointer almost 12 years
    I see you are using str. What is this? Edit: I see now that this is the factory method, not a variable name. So the factory will create blank strings.
  • Vikas Putcha
    Vikas Putcha almost 6 years
    This code helped me, I was looking for a way to print list of strings, where some of them have placeholders which i would like to replace with a constant. So I was looking for a way to use string.format such that it would not complain for strings which do not have place holders; string.format(cond=value)
  • 0dminnimda
    0dminnimda over 3 years
    although the question was asked more than 8 years ago, I think it might help other people who have this problem
  • void.pointer
    void.pointer over 3 years
    Yours isn't exactly what I asked for; the placeholders should be removed if they were not replaced.
  • 0dminnimda
    0dminnimda over 3 years
    @void.pointer, this is not a problem in the library there is also a function to satisfy this, i edited the answer
  • 0dminnimda
    0dminnimda over 3 years
    secretly say, if you followed the library link, then you would see an example of this behavior on the start page
  • 0dminnimda
    0dminnimda over 3 years
    although the library is young, its functionality will continue to grow. there will always be new ideas. (I already have some ideas for the behavior of the new formatters)
  • 0dminnimda
    0dminnimda over 3 years
    tell me should i add support for 2.7?