Python String Substitution

M

Murali

In Python, dictionaries can have any hashable value as a string. In
particular I can say

d = {}
d[(1,2)] = "Right"
d["(1,2)"] = "Wrong"
d["key"] = "test"

In order to print "test" using % substitution I can say

print "%(key)s" % d

Is there a way to print "Right" using % substitution?

print "%((1,2))s" % d

gives me "Wrong". Is there any syntax which will allow me to get
"Right" using % substitution?

- Murali
 
S

Steven D'Aprano

In Python, dictionaries can have any hashable value as a string.

No. Dictionaries can have any hashable value as a KEY. They are not
automatically converted to strings.
In particular I can say

d = {}
d[(1,2)] = "Right"
d["(1,2)"] = "Wrong"
d["key"] = "test"

In order to print "test" using % substitution I can say

print "%(key)s" % d

Yes, because the dictionary has a key which is the string "key".
Is there a way to print "Right" using % substitution?

print "%s" % "Right"
print "%s" % d[(1,2)]
print "%s%s" % ("R", "ight")

and so on.
print "%((1,2))s" % d

gives me "Wrong".

Yes, because the dictionary has a key which is the string "(1,2)".

Is there any syntax which will allow me to get "Right" using %
substitution?

You need to change your strategy. The dictionary form of string
substitution only works with keys which are strings. Look at it this way:

print "something %(x)s something" % somedict

"something %(x)s something" is a string, so all the substrings of it are
also strings, including "x". That's pretty obvious. But the same holds if
you change the x to something else:

print "something %(123.456)s something" % somedict

"123.456" is still a string.
 
J

John Bauman

Murali said:
In Python, dictionaries can have any hashable value as a string. In
particular I can say

d = {}
d[(1,2)] = "Right"
d["(1,2)"] = "Wrong"
d["key"] = "test"

In order to print "test" using % substitution I can say

print "%(key)s" % d

Is there a way to print "Right" using % substitution?

print "%((1,2))s" % d

gives me "Wrong". Is there any syntax which will allow me to get
"Right" using % substitution?
One way would be to make an adapter to convert that string to a tuple:
class adapter:
def __init__(self, dc):
self.dc = dc
def __getitem__(self,item):
return self.dc[eval(item)]

Then you could use this as:
print "%((1,2))s" % adapter(d)

I wouldn't actually recommend using eval in production code, due to the
possible security issues, but I'm sure you could replace it with some
more/better code. This is just an idea.
 
B

Bengt Richter

In Python, dictionaries can have any hashable value as a string. In
particular I can say

d = {}
d[(1,2)] = "Right"
d["(1,2)"] = "Wrong"
d["key"] = "test"

In order to print "test" using % substitution I can say

print "%(key)s" % d

Is there a way to print "Right" using % substitution?

print "%((1,2))s" % d

gives me "Wrong". Is there any syntax which will allow me to get
"Right" using % substitution?

You can modify the dict to try to convert the string to what it is
a source for, by eval, and try that as a key also, if you have no security worries
about malevolent format strings:
... def __getitem__(self, key):
... print repr(key)
... if key in self: return dict.__getitem__(self, key)
... else: return self[eval(key)]
...
>>> d = D()
>>> d[(1,2)] = "Right"
>>> d["key"] = "test"
>>> print "%(key)s" % d
'key'
test '(1,2)'
(1, 2)
Right
>>> d[123] = 'onetwothree'
>>> print "%(123)s" % d
'123'
123
onetwothree

Note recursive printing of converted key when the first one fails.
Of course if you _also_ define the string key for Wrong, that will
succeed, so it won't get converted to get Right:
>>> d["(1,2)"] = "Wrong"
>>> print "%((1,2))s" % d
'(1,2)'
Wrong
(1, 2)
'Right'

Do you have a real use case? Just curious.

Regards,
Bengt Richter
 
M

Murali

No. I dont have a real life example. I was explaining % substitution to
somebody and realized that I have only used it in the form where the
keys are strings. Was wondering if there is some special syntax already
part of python with which I can lookup the dictionary using a tuple as
a key.

- Murali
 
S

Steven D'Aprano

No. I dont have a real life example. I was explaining % substitution to
somebody and realized that I have only used it in the form where the
keys are strings. Was wondering if there is some special syntax already
part of python with which I can lookup the dictionary using a tuple as
a key.

print "%s" % some_dictionary[some_tuple]

Or for that matter:

print "%s" % some_dictionary[any hashable object at all]

What you can't do is use string interpolation like this:

print "%(123)s" % some_dictionary

unless the string "123" is a key in the dictionary. Having a key 123 will
not work, and the same for any other object.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top