If you are using Python 3.2+, use can use str.format_map().
For bond, bond:
from collections import defaultdict
'{bond}, {james} {bond}'.format_map(defaultdict(str, bond='bond'))
Result:
'bond, bond'
For bond, {james} bond:
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
'{bond}, {james} {bond}'.format_map(SafeDict(bond='bond'))
Result:
'bond, {james} bond'
In Python 2.6/2.7
For bond, bond:
from collections import defaultdict
import string
string.Formatter().vformat('{bond}, {james} {bond}', (), defaultdict(str, bond='bond'))
Result:
'bond, bond'
For bond, {james} bond:
from collections import defaultdict
import string
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
string.Formatter().vformat('{bond}, {james} {bond}', (), SafeDict(bond='bond'))
Result:
'bond, {james} bond'
Answer from falsetru on Stack OverflowIf you are using Python 3.2+, use can use str.format_map().
For bond, bond:
from collections import defaultdict
'{bond}, {james} {bond}'.format_map(defaultdict(str, bond='bond'))
Result:
'bond, bond'
For bond, {james} bond:
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
'{bond}, {james} {bond}'.format_map(SafeDict(bond='bond'))
Result:
'bond, {james} bond'
In Python 2.6/2.7
For bond, bond:
from collections import defaultdict
import string
string.Formatter().vformat('{bond}, {james} {bond}', (), defaultdict(str, bond='bond'))
Result:
'bond, bond'
For bond, {james} bond:
from collections import defaultdict
import string
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
string.Formatter().vformat('{bond}, {james} {bond}', (), SafeDict(bond='bond'))
Result:
'bond, {james} bond'
You could use a template string with the safe_substitute method.
from string import Template
tpl = Template('$bond, $james $bond')
action = tpl.safe_substitute({'bond': 'bond'})
python - Why does `str.format()` ignore additional/unused arguments? - Stack Overflow
How to get .format() to ignore a specific {} that is in a string?
Why does Python string formatting silently ignore mismatched argument counts with class instances? - Stack Overflow
Do not use Python's str.format() for expanding placeholders in commands
If you are assigning None to your variable, you will have to set some kind of condition around controlling what output you want. Here is a simple example:
"{} {}".format(foo, "" if bar is None else bar)
Another way of looking at the above that behaves the same way, is writing it this way as well:
"{} {}".format(foo, bar if bar is not None else "")
def none_to_empty(s):
return "" if s is None else s
def format_without_nones(format_string, *args):
return format_string.format(*map(none_to_empty, args))
format_without_nones("{} {}", foo, bar)
Look up varargs and the map function if you don't understand how format_without_nones works. It's just equivalent to saying
"{} {}".format(none_to_empty(foo), none_to_empty(bar))
which doesn't look as pretty since you might have to repeat none_to_empty a lot of time. But none_to_empty can also be used directly if you only want to apply it to some arguments but let None appear for others, e.g.:
"{} {}".format(foo, none_to_empty(bar))
which is still nicer than having "" if bar is None else bar for every single bar.
I have a text file that gets read in to the program, and it also contains a JSON file.
An example of what I'm talking about is this:
Hello, {}. Welcome to /r/{}. This is a JSON file.
---
{
"key": "value"
}
That is stored in a text file that we will call example.txt. I read the file in as such:
def read_text_file(file_name):
with open(file_name, "r") as file:
return file.read()
my_string = read_text_file("example.txt")
formatted_string = my_string.format(username, subreddit)
However, because the dictionary also has a {} in it, .format() seems to expect a third argument with .format(). Is there a way to make it ignore the third one so that I don't get a KeyError exception?
So I wanna do
print("Accuracy is %.2f%" % (accuracy))but it just says incomplete format because its taking the second % as a format specifier. The one way I have around this is by doing
print("Accuracy is %.2f" % (accuracy),"%")but it leaves a space between the number and the %.
Actually, as of writing the post I realised I can split it into two print statements and do an end="" and that should print the desired output. Just wanna know if there's any better way of doing this because using \ does not work to make python ignore the %.
You need to double the {{ and }}:
>>> x = " {{ Hello }} {0} "
>>> print(x.format(42))
' { Hello } 42 '
Here's the relevant part of the Python documentation for format string syntax:
Format strings contain “replacement fields” surrounded by curly braces
{}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a brace character in the literal text, it can be escaped by doubling:{{and}}.
Python 3.6+ (2017)
In the recent versions of Python one would use f-strings (see also PEP498).
With f-strings one should use double {{ or }}
n = 42
print(f" {{Hello}} {n} ")
produces the desired
{Hello} 42
If you need to resolve an expression in the brackets instead of using literal text you'll need three sets of brackets:
hello = "HELLO"
print(f"{{{hello.lower()}}}")
produces
{hello}
The official solution (Python 3 Docs) for strings in format mappings is to subclass the dict class and to define the magic-method __missing__(). This method is called whenever a key is missing, and what it returns is used for the string formatting instead:
class format_dict(dict):
def __missing__(self, key):
return "..."
d = format_dict({"foo": "name"})
print("My %(foo)s is %(bar)s" % d) # "My name is ..."
print("My {foo} is {bar}".format(**d)) # "My name is ..."
Edit: the second print() works in Python 3.5.3, but it does not in e.g. 3.7.2: KeyError: 'bar' is raised and I couldn't find a way to catch it.
After some experiments, I found a difference in Python's behavior. In v3.5.3, the calls are __getitem__(self, "foo") which succeeds and __getitem__(self, "bar") which can not find the key "bar", therefore it calls __missing__(self, "bar") to handle the missing key without throwing a KeyError. In v3.7.2, __getattribute__(self, "keys") is called internally. The built-in keys() method is used to return an iterator over the keys, which yields "foo", __getitem__("foo") succeeds, then the iterator is exhausted. For {bar} from the format string there is no key "bar". __getitem__() and hence __missing_() are not called to handle the situation. Instead, the KeyError is thrown. I don't know how one could catch it, if at all.
In Python 3.2+ you should use format_map() instead (also see Python Bug Tracker - Issue 6081):
from collections import defaultdict
d = defaultdict(lambda: "...")
d.update({"foo": "name"})
print("My {foo} is {bar}".format_map(d)) # "My name is ..."
If you want to keep the placeholders, you can do:
class Default(dict):
def __missing__(self, key):
return key.join("{}")
d = Default({"foo": "name"})
print("My {foo} is {bar}".format_map(d)) # "My name is {bar}"
As you can see, format_map() does call __missing__().
The following appears to be the most compatible solution as it also works in older Python versions including 2.x (I tested v2.7.15):
class Default(dict):
def __missing__(self, key):
return key.join("{}")
d = Default({"foo": "name"})
import string
print(string.Formatter().vformat("My {foo} is {bar}", (), d)) # "My name is {bar}"
To keep placeholders as-is including the format spec (e.g. {bar:<15}) the Formatter needs to be subclassed:
import string
class Unformatted:
def __init__(self, key):
self.key = key
def __format__(self, format_spec):
return "{{{}{}}}".format(self.key, ":" + format_spec if format_spec else "")
class Formatter(string.Formatter):
def get_value(self, key, args, kwargs):
if isinstance(key, int):
try:
return args[key]
except IndexError:
return Unformatted(key)
else:
try:
return kwargs[key]
except KeyError:
return Unformatted(key)
f = Formatter()
s1 = f.vformat("My {0} {1} {foo:<10} is {bar:<15}!", ["real"], {"foo": "name"})
s2 = f.vformat(s1, [None, "actual"], {"bar":"Geraldine"})
print(s1) # "My real {1} name is {bar:<15}!"
print(s2) # "My real actual name is Geraldine !"
Note that the placeholder indices are not changed ({1} remains in the string without a {0}), and in order to substitute {1} you need to pass an array with any odd first element and what you want to substitute the remaining placeholder with as second element (e.g. [None, "actual"]).
You can also call the format() method with positional and named arguments:
s1 = f.format("My {0} {1} {foo:<10} is {bar:<15}!", "real", foo="name")
s2 = f.format(s1, None, "actual", bar="Geraldine")
str.format() doesn't expect a mapping object. Try this:
from collections import defaultdict
d = defaultdict(str)
d['error2'] = "success"
s = "i am an {0[error]} example string {0[error2]}"
print s.format(d)
You make a defaultdict with a str() factory that returns "". Then you make one key for the defaultdict. In the format string, you access keys of the first object passed. This has the advantage of allowing you to pass other keys and values, as long as your defaultdict is the first argument to format().
Also, see http://bugs.python.org/issue6081
Double %% the single % to escape it:
SELECT_CLAUSE += ", IF(%s IS NULL, -1, %s=%%s) AS %s_score" % (
field, field, field
)
Where is the StringBorg that we direly need? That would make this safe.
You could use str.format() to do that, for example:
field = 'name'
SELECT_CLAUSE += ', IF({name} IS NULL, -1, {name}=%s) AS {name}_score'.format(name=field)
In addition, if you're using python 3.6+ you could use format string by specifying variable name in braces:
field = 'name'
SELECT_CLAUSE += f', IF({field} IS NULL, -1, {field}=%s) AS {field}_score'
Hey guys,
I'm working in a very specific enviroment and I have a scheme file where I replace keys with the format function. The file might look like this:
1: {code1}
2: {code2}
3: {code3}I want that other persons can change the format file and add {code} tags. My program uses this file and replaces the values, but the amount of {code} blocks varies.
So at the moment I generate a dict with the code tags, and replace them in that string (which got loaded from the file)
code_tags = {"code1": "ABC", "code2": "DEF"}
file_content.format(**code_tags)A problem occurs when there are more keys in the scheme file than keys generated from my program (KeyError). How can I put in an empty string for tags which got not specified in code_tags?
I thought about crawling the file and find every tag, compare, and add missing to the dict with and emptry string. But that's kinda hask-ish and maybe not the cleanest style.
How would you solve the problem?
You could (and should) use the new string .format() method (if you have Python 2.6 or higher) instead:
"Day old bread, 50% sale {0}".format("today")
The manual can be found here.
The docs also say that the old % formatting will eventually be removed from the language, although that will surely take some time. The new formatting methods are way more powerful, so that's a Good Thing.
Not really - escaping your % signs is the price you pay for using string formatting. You could use string concatenation instead: 'Day old bread, 50% sale ' + whichday if that helps...