I have recently started to learn Python and I am hoping that you will be able to help me with a question that has been bothering me. I have been learning Python online with Learn Python The Hard Way. In Exercise 6, I came across a problem where I was using the %r string formatting operation and it was resulting in two different strings. When I printed one string, I got the string with the single quotes (' '). With another I was getting double quotes (" ").
Here is the code:
x = "There are %d types of people." % 10
binary = "binary"
do_not = "don't"
y = "Those who know %s and those who %s." % (binary, do_not)
print "I said: %r." % x
print "I also said: %r." % y
The result from the first print statement:
I said: 'There are 10 types of people.'.
The result from the second print statement:
I also said: "Those who know binary and those who don't.".
I want to know why one of the statements had a result with the single quotes (' ') and another with (" ").
]
P.S. I am using Python 2.7.
%r is getting the repr version of the string:
>>> x = 'here'
>>> print repr(x)
'here'
You see, single quotes are what are normally used. In the case of y, however, you have a single quote (apostrophe) inside the string. Well, the repr of an object is often defined so that evaluating it as code is equal to the original object. If Python were to use single quotes, that would result in an error:
>>> x = 'those who don't'
File "<stdin>", line 1
x = 'those who don't'
^
SyntaxError: invalid syntax
so it uses double quotes instead.
Notice this line -> do_not = "don't". There is a single quote in this string, that means that single quote has to be escaped; otherwise where would the interpreter know where a string began and ended? Python knows to use "" to represent this string literal.
If we remove the ', then we can expect a single quote surrounding the string:
do_not = "dont"
>>> I also said: 'Those who know binary and those who dont.'.
Single vs. double quotes in python.
Related
I have the following code
test = "have it break."
selectiveEscape = "Print percent % in sentence and not %s" % test
print(selectiveEscape)
I would like to get the output:
Print percent % in sentence and not have it break.
What actually happens:
selectiveEscape = "Use percent % in sentence and not %s" % test
TypeError: %d format: a number is required, not str
>>> test = "have it break."
>>> selectiveEscape = "Print percent %% in sentence and not %s" % test
>>> print selectiveEscape
Print percent % in sentence and not have it break.
Alternatively, as of Python 2.6, you can use new string formatting (described in PEP 3101):
'Print percent % in sentence and not {0}'.format(test)
which is especially handy as your strings get more complicated.
try using %% to print % sign .
You can't selectively escape %, as % always has a special meaning depending on the following character.
In the documentation of Python, at the bottem of the second table in that section, it states:
'%' No argument is converted, results in a '%' character in the result.
Therefore you should use:
selectiveEscape = "Print percent %% in sentence and not %s" % (test, )
(please note the expicit change to tuple as argument to %)
Without knowing about the above, I would have done:
selectiveEscape = "Print percent %s in sentence and not %s" % ('%', test)
with the knowledge you obviously already had.
If you are using Python 3.6 or newer, you can use f-string:
>>> test = "have it break."
>>> selectiveEscape = f"Print percent % in sentence and not {test}"
>>> print(selectiveEscape)
... Print percent % in sentence and not have it break.
If the formatting template was read from a file, and you cannot ensure the content doubles the percent sign, then you probably have to detect the percent character and decide programmatically whether it is the start of a placeholder or not. Then the parser should also recognize sequences like %d (and other letters that can be used), but also %(xxx)s etc.
Similar problem can be observed with the new formats -- the text can contain curly braces.
I have a string with unknown number of %s that need to be formatted with a single string.
For instance, if I had the string "%s some %s words %s" and wanted to format it with the word house it should output "house some house words house"
Doing the following gives me an error:
>>> "%s some %s words %s" % ("house")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
So, I decided to do the following, which works but seem to be overly complex for such a simple problem.
var = "house"
tup = (var,)
while True:
try:
print "%s some %s words %s" % tup
break
except:
tup += (var,)
Is there a more pythonic way of doing this?
If you know for sure you're subbing %s you can do it like this:
var = "house"
tup = (var,)
txt = "%s some %s words %s"
print txt % (tup * txt.count("%s"))
But a better solution is to use str.format() which uses a different syntax, but lets you specify items by number, so you can reuse them:
var = "house"
txt = "{0} some {0} words {0}"
print txt.format(var)
Here are a few options:
Format string (and Formatter class)
Using str.format is the most pythonic way and pretty simple to read. Either style is popular:
Position arguments
'{0} some {0} words {0}'.format('house')
Named arguments
'{word} some {word} words {word}'.format(word='house')
In a comment you mentioned preserving the original format string because of other legacy code. You could hack around that like so:
'%s some %s words %s'.replace('%s', '{0}').format('house')
(I don't recommend it but you could "short circuit" this idea line by using 'house' in the replace call instead of '{0}'.)
That said, I really think changing the template string in the first place is a better idea.
Template strings
One more alternative comes to mind after glancing at the string docs: the older string.Template class. By default it substitutes $-based values, but you can subclass it overriding the delimiter character. For example:
class MyTemplate(Template):
"""
Overriding default to maintain compatibility with legacy code.
"""
delimiter = '%'
t = MyTemplate('%s some %s words %s')
t.substitute(s='house')
Remember this is less common but you could write it once and re-use it every time you work with a string like this (assuming there's only one input value being substituted in). Writing it once is Pythonic at least!
Literal string interpolation
In Python 3.6, Ruby-style string interpolation is another option that the community hasn't come to a consensus on yet. For example:
s = 'house'
f'{s} some {s} words {s}'
Why not use format?
"{0} some {0} words {0}".format("house")
I have
cmd=arg[3:]
which gives for e.g.
['file python parameter1=5 parameter2=456 ']
When I am printing I want to print in the format - python file parameters..
I tried
print "%s %s %s" % (string.split(cmd[0])[1],string.split(cmd[0])[0],string.split(cmd[0])[2:])
which gives
python file ['parameter1=5 parameter2=456 ']
How can i get the parameters part printed without the square braces or the quotes?
Thanks.
For the last part how can I print
You are asking Python to turn a list into a string. This is why you are seeing the brackets and quotes. All you need to do is use join to make it a string again.
" ".join(string.split(cmd[0])[2:])
or if you really prefer the string module
string.join(" ", string.split(cmd[0])[2:])
I would prefer to see the code written like this if I were doing a code review:
fname, interp, args = cmd[0].split(" ", 2)
print "%s %s %s" % (interp, fname, args)
Use the format method in preference to %-style string formatting.
print "{0[1]} {0[0]} {0[2]}".format(cmd[0].split(None, 2))
You could try something like that:
' '.join(cmd[0].split()[2:])
instead of:
string.split(cmd[0])[2:]
Also, I would recommend you to use an intermediate variable to avoid to do the same split 3 times... Or even better :
print ' '.join(cmd[0].split(' ', 2))
or actually simply:
print cmd[0]
But I guess you don't want to only print it...
for i in range(2, job_count+1):
job_count_array['//form[#id='SubAvailSelectForm']/font/table[2]/tbody/tr[%d]/td[1]/small' % i] = sel.get_text("//form[#id='SubAvailSelectForm']/font/table[2]/tbody/tr[%d]/td[1]/small" % i)
I am getting a syntax error with the value side of this dictionary entry. Let me know what looks wrong to you. The interpreter is pointing to the % i). Thanks!
Look at the syntax highlighting. You can’t just put a plain ol’ ' in your '-delimited string.
Escape them as \', or change your quotes to be consistent with the second string:
for i in range(2, job_count+1):
job_count_array["//form[#id='SubAvailSelectForm']/font/table[2]/tbody/tr[%d]/td[1]/small" % i] = sel.get_text("//form[#id='SubAvailSelectForm']/font/table[2]/tbody/tr[%d]/td[1]/small" % i)
Your problem is here:
job_count_array['//form[#id='SubAvailSelectForm']/font/table[2]/tbody/tr[%d]/td[1]/small' % i]...
do "//form..." instead of '//form...': double quotes instead of single. As in your string you have 'SubAvailSelectForm', which is quoted with single quotes. So either make your string double-quoted, or escape single quotes in your string: '\''
You have single quotes inside single quotes. The interpreter is confused :)
s = "A Colon is beside me"
print s,":"
I should get
A Colon is beside me :
But I wanna get
>>>A Colon is beside me:
How?
Concatenate the strings:
print s + ':'
or use string formatting:
print '{0}:'.format(s)
On python 3, the print() function can also be told to use an empty separator between multiple arguments, instead of a space:
print(s, ':', sep='')
This definatly works. (I am new to the site and I have put normal text not code!?)
print "%s:" % s
The %s means insert a variable here and the second s means insert the specific variable 's
This is for summarization purpose.
There are four ways to print statement:
s = "A Colon is beside me"
Data Type Parsing Mode:
print("%s:" %s)
Variables Concatenation Mode:
print(s+":")
format() method:
print("{}:".format(s))
Using Built-in function:
print(s,':',sep='')