Reputation: 911
I am creating a string of a dictionary (to add to a .txt file later) in Python 3.6.6.
When I hard code the string of the dictionary, I don't get any problems:
my_string = '{"source": "s3://some_s3_bucket/random_filename.csv"} \n'
print(my_string)
outputs
{"source": "s3://some_s3_bucket/random_filename.csv"}
However, when I try to substitute the hard-coded filepath for variables, it appears that Python starts assuming that "source" is a variable I want to substitute:
bucket = "some_s3_bucket"
filename = "random_filename.csv"
my_new_string = '{"source": "s3://{0}/{1}"} \n'.format(bucket, filename)
print(my_new_string)
outputs
KeyError Traceback (most recent call last) in module
--> 1 my_new_string = '{"source": "s3://{0}/{1}"} \n'.format(bucket, filename)
2 print(my_new_string)KeyError: '"source"'
How should I be formatting this string for Python to properly read my bucket and filename variables?
Upvotes: 0
Views: 175
Reputation: 911
the problem is with the curly braces using:
my_new_string = '{{"source": "s3://{}/{}"}}'.format(bucket, filename)
outputed this
{"source": "s3://some_s3_bucket/random_filename.csv"}
Upvotes: 0
Reputation: 198516
format
triggers replacements on curly braces. You have a curly brace at the start of the string. Incidentally, after a field name, you can append format modifiers, separated by a colon. Consequently, everything between a curly brace and a colon is taken as a field name, and you don't have a field named "source"
(together with the quotes).
To output a curly brace, double it:
my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)
but Talon's comment is right, using json
module would be better than making JSON by hand, since the variables' values might need escaping, in the general case. Since you will then have no braces you'd need to output, your format
problem disappears:
import json
my_new_string = json.dumps({"source": "s3://{0}/{1}".format(bucket, filename) })
Upvotes: 5
Reputation: 29
The problem is those { and } characters you have there that don't specify a key for formatting.
bucket = "some_s3_bucket"
filename = "random_filename.csv"
my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)
print(my_new_string)
Upvotes: 0
Reputation: 12927
str.format()
uses {}
characters as placeholders for parameters to be formatted. You used {
at the beginning of your format string, and that causes the problem. What you want to do is to use double braces {{
& }}
where they need to be taken as literal braces rather than substituted:
my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)
Besides, this is a poor way to generate JSON data (see the comment by Talon).
Upvotes: 1
Reputation: 795
You are using string format so you have to use double {{
data }}
In [1]: bucket = "some_s3_bucket"
...: filename = "random_filename.csv"
...: my_new_string = '{{"source": "s3://{0}/{1}"}} \n'.format(bucket, filename)
...: print(my_new_string)
{"source": "s3://some_s3_bucket/random_filename.csv"\}
Check this for more information How can I print literal curly-brace characters in python string and also use .format on it?
Upvotes: 1