How can I programmatically build a string containing escaped characters to pass as an argument to a function in Python?

Question:

I am trying to build the string below programatically:

string0 = 'case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end'

I do:

a_list = ['a','b']
string = '(\''+'\',\''.join(a_list)+'\')'
string2 = 'case when "LETTER" in ' + string + ' then "LETTER" else 'other letter' end'

however, string0 == string2 returns False

Answers:

If you use a list comprehension, it gets a bit easier:

string0 = 'case when "LETTER" in '
string1 = ' then "LETTER" else 'other letter' end'
lst = ['a', 'b']
term = '(' + ','.join(["'" + x + "'" for x in lst]) + ')'
output = string0 + term + string1
print(output)

# case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end
Answered By: Tim Biegeleisen

You can build string2 like this:

my_list = ['a', 'b']
string0 = 'case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end'
string = '('{}')'.format('',''.join(my_list))
string2 = 'case when "LETTER" in {} then "LETTER" else 'other letter' end'.format(string)

string0 == string2 # returns True
Answered By: Ake

You’re using backslashes too much. You gotta use only as many as in string0. So "just" '(''+'',''.join(list)+'')'. And if you switch the outer quotes to ", then you don’t need escapes with ' at all – "('" + "','".join(list) + "')"

How to do it in a nicer way:

Let’s do it the other way around, we have your string0:

string0 = 'case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end'

Let’s just get everything you wanted out and add it as a whole formatting:

ab_string = '('a','b')'
string0 = f'case when "LETTER" in {ab_string} then "LETTER" else 'other letter' end'

Now, let’s take a look at ab_string: '('a','b')'. If we change the quotes to double, we will see those are just "('a','b')" – the escapes were only there to avoid collision with the outer quotes of string0.

So we can just do the thing you had:

ab_list = ['a','b']
ab_string = "('" + "','".join(ab_list) + "')"
string0 = 'case when "LETTER" in ' + string + ' then "LETTER" else 'other letter' end'

Now, a hack: Do you know how printing a list itself looks like? ['a', 'b'], right? So we can even get a hacky way of just replacing the outer [] – cut the edges off using indexes, add ()

ab_list = ['a', 'b']
ab_string = f'({str(ab_list)[1:-1]})'
string0 = f'case when "LETTER" in {ab_string} then "LETTER" else 'other letter' end'
Answered By: h4z3

You can use this command:

string = '(' + ','.join(f"'{x}'" for x in list) + ')'

When you keep other comands from your question as they are, then string0 and string2 will be the same.

But it is not clear, if it is what you really want.

Some backslash characters in the string0 definition are redundant and has no meaning. For example:

>>> test = 'case when "LETTER"'
>>> print(test)
case when "LETTER"

>>> test2 = 'case when "LETTER"'
>>> print(test2)
case when "LETTER"
>>> test == test2
True
Answered By: eNca

Printing the strings would help you to see the difference.
The reason string0 == string2 returns False in your code is due to the difference in escaping the backslashes. When you manually create string0, you escape the double quotes (") with backslashes (), resulting in literal double quotes in the string. However, in string2, you’re escaping the single quotes (') within the string that represents the list.

Solution:

lst = ['a', 'b']

string0 = 'case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end'

string = "('{}')".format("','".join(lst))
string2 = 'case when "LETTER" in ' + string + ' then "LETTER" else 'other letter' end'

print(string0)
print(string2)
print(string0 == string2)

Output of the code above:

case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end
case when "LETTER" in ('a','b') then "LETTER" else 'other letter' end
True
Answered By: David
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.