How to Format a String Using a Dictionary in Python-3.X

How do I format a string using a dictionary in python-3.x?

Since the question is specific to Python 3, here's using the new f-string syntax, available since Python 3.6:

>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091

Note the outer single quotes and inner double quotes (you could also do it the other way around).

How to use str.format() with a dictionary in Python?

Should be

test = "I have one {fruit} on the {place}.".format(**dic)

Note the **. format() does not accept a single dictionary, but rather keyword arguments.

String format for dictionary with f-strings

You could iterate through the key-value pairs, and print the output accordingly:

dic = {'A': 1, 'B': 2, 'C': 3}
print('This is output', end=' ')
for k,v in dic.items():
print(str(k) + ':' + str(v), end=' ')

Output

This is output A:1 B:2 C:3 

Alternatively you could concatenate the string (same output):

dic = {'A': 1, 'B': 2, 'C': 3}
s = ''
for k,v in dic.items():
s += f'{k}:{v} ' #thanks to @blueteeth
print('This is output', s.strip())

Format a string using dictionary unpacking (Python 3.9)

The problem is that the keys are (string) of integer and this is in conflict with the notation for a substitution with list (2nd example). This is due (I guess) by the implementation of __getitem__, here some more examples.

Here with non-integer keys:

mydict = {'0.': '5', '1.': 'ZIDANE'}  # with float-keys it works
print('{d[0.]} {d[1.]}'.format(d=mydict))

Here an example with a list

mylst = ['5', 'ZIDANE']
print('{l[0]} {l[1]}'.format(l=mylst))

A similar side-effect is encountered with dictionaries:

print(dict(a=5, b='ZIDANE'))
#{'a': 5, 'b': 'ZIDANE'}
print(dict(1=5, 2='ZIDANE'))
#SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
print(dict('1'=5, '2'='ZIDANE'))
#SyntaxError: expression cannot contain assignment, perhaps you meant "=="?

Python 3.2: How to pass a dictionary into str.format()

This does the job:

stats = { 'copied': 5, 'skipped': 14 }
print( 'Copied: {copied}, Skipped: {skipped}'.format( **stats ) ) #use ** to "unpack" a dictionary

For more info please refer to:

  • http://docs.python.org/py3k/library/string.html#format-examples
    and
  • http://docs.python.org/py3k/tutorial/controlflow.html#keyword-arguments

python3 nested dictionary unpack for format string

Using f-string

config = {
"TEST": "TEST",
"TEST1": "TEST1",
"TEST2": {
"TEST21": "TEST21"
}
}

query_2 = f"""
{config['TEST']} {config['TEST1']}
{config['TEST2']['TEST21']}
"""

print(query_2)

Note, if query is sql query, there is probably better way to do what you do, not using string formatting

How to use .format(**dict) with a dictionary that gets updated in a loop?

You overwrote your format string (which contains placeholders for new values) with a formatted string (where the placeholders have been replaced with the data they were holding a place for). From the second iteration onwards, there is no {lat} or {lon} placeholder in the string. If you printed url immediately after the first inner loop ran, you'd see the contents were now:

url = 'https://some.url.com/{zoom}/2835/4464.{ext}'

which still has placeholders for {zoom} and {ext}, but has fixed values for the other placeholders, so there is nothing to update on future loops.

If you don't want that to happen, don't assign back to url after formatting, use a different name for the partially formatted string (or use a list of such partially formatted strings if you want one for every combination of lat and lon).

How can I do a dictionary format with f-string in Python 3 .6?

Well, a quote for the dictionary key is needed.

f'My name {person["name"]} and my age {person["age"]}'

Convert a formatted string to a dictionary

There is a JSON library, which already provides the basic functionality of loading strings to dictionaries. It seems like it would be fairly simple to have a string formatting function that converts input string to JSON, and then load it using the library function. Given that, this should work?

import json
import string
from pprint import pprint

def convert(input_string):
""" Given an input string, convert to JSON and load to dict"""

token_characters = string.ascii_letters + string.digits
json_str = str()

token_marker = False
for index, char in enumerate(input_string):
if char == "=":
json_str += ":"
elif char in token_characters and not token_marker:
token_marker = True
json_str += '"%s' % char
elif char not in token_characters and token_marker:
token_marker = False
json_str += '"%s' % char
else:
json_str += char

return json.loads(json_str)

if __name__ == "__main__":
a = "{ currNode = {currIndex = 23, currElem = 0x0}, size = 23}"
pprint(convert(a))

This basically just parses the string, looks out for characters that could be keys or values (or tokens in the code), and then quotes them to make a JSON compatible string. You have to correctly define your token characters for it to work though.

You could in theory change this to have the reverse logic where you treat everything other than "{,= }" like a token character. The deciding factor would be depending on whether or not you had consistent separators or characters (or which you would have the write the fewest tests for). This latter approach seems like it may be better though, Here is an example of the logic flipped version:

def convert2(input_string):
""" given an input string, convert to JSON and load"""

not_token_characters = "{=,: }"
json_str = str()

token_marker = False
for index, char in enumerate(input_string):
if char == "=":
json_str += ":"
elif char not in not_token_characters and not token_marker:
token_marker = True
json_str += '"%s' % char
elif char in not_token_characters and token_marker:
token_marker = False
json_str += '"%s' % char
else:
json_str += char

return json.loads(json_str)

To make this really general purpose you'd probably have to add some additional error checking, but given the example this should get you going I hope.



Related Topics



Leave a reply



Submit