Using String Formatting to pull data from a dictionary - python

How do I use string formatting to call information from a dictionary?
Here's what I attempted so far (probably quite bad...)
value = raw_input("Indicate a number: ")
print number_stats["chm%"] % (value,)
The dictionary number_stats holds information about values "chm1", "chm2", etc.
I get a key error, which confuses me because the item chm1 is definitely stored in my dictionary.
Is there a better way to do this?

When you do number_stats["chm%"] % (value,), you are doing number_stats["chm%"] first and then applying % (value,) to the result. What you want is to apply the % directly to the string:
number_stats["chm%s" % (value,)]
Note that you need %s; % by itself is not a valid string substitution.
However, there is probably a better way to do it. Why does your dictionary have keys like "chm1" and "chm2" instead of just having the numbers be the keys themselves (i.e., have keys 1 and 2)? Then you could just do number_stats[value]. (Or if you read value from raw_input you'd need number_stats[int(value)]

Use like this. You have to use string formatting inside square brackets
>>> number_stats={'a1': 1}
>>>
>>> print number_stats['a%s' % 1]
1
>>>

print number_stats["chm%s" % (value)]
should work.
But you should do this instead:
print number_stats.get("chm%s" % (value), "some_default_value")
To avoid crashing if the user enters an invalid key. See this for more info on the get method.

As an alternative you could use the string format method...
value = input("Indicate a number: ")
print number_stats["chm{}".format(value)]

Related

String formatting using integer type key in dictionary returns KeyError in Python 2,works with string type key

I am working through Google Python Class and came across using key value in a dictionary for formatting a string
hash = {}
hash['word'] = 'garfield'
hash['count'] = 42
s = 'I want %(count)d copies of %(word)s' % hash
# %d for int, %s for string
# 'I want 42 copies of garfield'
Here is my attempt.
my_dict={}
my_dict['1']=50
my_dict['2']=100
s='%(1)d of %(2)d' % my_dict
print s
#Output:
# 50 of 100
#Perfect!
It goes wrong when I use integer keys.
my_dict={}
my_dict[1]=50
my_dict[2]=100
s='%(1)d of %(2)d' % my_dict
print s
#Output:
#Traceback (most recent call last):
#File "dictformat.py", line 4, in <module>
#s='%(1)d of %(2)d' % my_dict
#KeyError: '1'
Dictionary is formed and printed properly.I see keys of integer type are valid from here
my_dict={}
my_dict[1]=50
my_dict[2]=100
print my_dict
#Output:
#{1: 50, 2: 100}
I understand there is a .format in python3 as referred in format string using dict Python3 and Python string formatting: % vs. .format
But,I want to know what is wrong with my understanding or if integer keys should not be used for string formatting?
Looking at the error message KeyError: '1' that you get when using integer keys, the key that is searched in the dictionary has type str. If the % behaved as you intended it to, thus looking for an integer key and not finding it, the error would have been KeyError: 1.
Summarizing, the problem you have is related to the type of the key that % uses in the dictionary lookup, which is str and not int. Thus only str keys can be used, no automatic conversion happens between strings and integers in Python.
You could youse f
my_dict={}
my_dict[1]=50
my_dict[2]=100
s = f"{my_dict[1]} of {my_dict[2]}"
print(s)
Output:
50 of 100
[Finished in 0.2s]
Other way
my_dict={}
my_dict[1]=50
my_dict[2]=100
s = "{} of {}".format(*my_dict.values())
print(s)
Output:
50 of 100
[Finished in 0.2s]

Print data in a dictionary nested in a dictionary, in a nice way?

Trying to display data in a structure that is a dictionary contained in a defaultdict
dictionary=defaultdic(dict)
Example
defaultdict = {key1} :
{subkey1}:
(val1,
val2,
val3)
{subkey2}:
(val4,
val5,
val6)
{key2} :
{subkey3}:
(val7,
val8,
val9),
{subkey4}:
(val10,
val11,
val12)
I tried to do
for key in dictionary.iterkeys():
print key # This will return me the key
for items in dictionary[key]:
print items # This will return me the subkey
for values in dictionary[key][items]:
print values #this return the values for each subkey)
The problem is that I just get printed out a flat list of items; which is almost impossible to follow when you have too many items and keys.
How do you properly print such complex structures, to present them in a way that does not make you rip your eyes out? I tried with pprint and json.dumps but neither was making the situation better. Ideally I would like to have it printed as in my example, but I can't see a simple way to do so, without going trough complex string manipulation to format the print output.
Python has the PrettyPrint module just for this purpose. Note that defaultdicts won't print nicely, but if you convert back to a regular dict first it'll do fine.
from pprint import pprint
pprint(dict(dictionary))
Use indentation to print them out so your eye can visually see the structure.
for key in dictionary.iterkeys():
print key # This will return me the key
for items in dictionary[key]:
print(" %s" % items) # This will return me the subkey
for values in dictionary[key][items]:
print(" %s" % values) #this return the values for each subkey)
You can also substitute the space characters for \t to use a tab character; both will work fine. You may also have to use repr(values) or str(values) to explicitly get a string representation of them, if Python complains about the objects not being able to be formatted as a String.

Python / json.load gives exception

I have the following line:
BL: {version: 2, revision: 1}
I want to parse it, so that I will get in one variable BL, and on the other, I will get
[[version, revision], [2,1]]
I have the following code:
for line in file:
print line.split(':',1)[0]; gives me the first word (BL)
print line.split(': ',1)[1]
data = json.loads(json.dumps(line.split(': ',1)[1]));
The problem is that data is not contained the data as variable, so when I do data[0], I get the char: {
What the correct way to do that?
Your JSON is not valid since it's keys are not valid (you probably want strings there).
To get around it you could do something hacky like:
# give value to non-string keys, to use in eval
version = "version"
revision = "revision"
d = eval(line.split(": ", 1)[1])
print [d.keys(), d.values()]
This requires you to know all keys in advance.
I recommend you fix your input-generating script instead.
I always avoid eval.

Iterate a tuple of dictionaries and pass the nested dictionaries to a function

#!/usr/bin/python -tt
# A dictionary Of Each New SSID
WirelessNetwork = {}
WirelessNetwork['name'] = 'baz'
WirelessNetwork['type'] = 'bar'
WirelessNetwork['pass'] = 'foo'
# A list of all SSIDs
networkAddList = (WirelessNetwork)
def addWireless(passedDict={}):
print 'Adding SSID: %s' % passedDict['name']
print 'Of type: %s' % passedDict['type']
print 'With Password: %s' % passedDict['pass']
for networkDict in networkAddList:
addWireless(networkDict)
So I have a List "networkAddList" full of dictionaries ,i.e. "WirelessNetwork".
I want to iterate that list "for networkDict in networkAddList"
and pass the dictionary itself to my function "addWireless"
When I run the sample code above I get the following error:
TypeError: 'string indices must be integers, not str'
Which makes me think that python thinks passedDict is a string, thus thinking I want string indices i.e. 0 or something rather then the key 'name'. I'm new to python but I am going to have to do this kind of thing a lot so I hope somebody can point me in the right direction as I think its pretty simple. But I can't change the basic idea , i.e. a list of dictionaries.
When debugging in python you can confirm your suspicion that the value being passed is a string with the type function:
print type(passedDict)
When you create your tuple with one element, you need a trailing ",". Also note that a tuple is different from a list in python. The primary difference is that tuples are immutable and lists are not.
#!/usr/bin/python -tt
# A dictionary Of Each New SSID
WirelessNetwork = {}
WirelessNetwork['name'] = 'baz'
WirelessNetwork['type'] = 'bar'
WirelessNetwork['pass'] = 'foo'
# A list of all SSIDs
networkAddList = (WirelessNetwork,)
def addWireless(passedDict={}):
print 'Adding SSID: %s' % passedDict['name']
print 'Of type: %s' % passedDict['type']
print 'With Password: %s' % passedDict['pass']
for networkDict in networkAddList:
addWireless(networkDict)
this is not a list, is the value itself
# A list of all SSIDs
networkAddList = (WirelessNetwork)
with a comma becomes a list
# A list of all SSIDs
networkAddList = (WirelessNetwork,)
Actually it's not a list, even with a comma. It's a tuple, which is immutable. I bring this up in case your code is wanting to append anything to this later.
networkAddList = [WirelessNetwork] # or, list(WirelessNetwork)
Just ran a quick check of the types being referenced, and I'm believing that you were only missing a serial comma (in WirelessNetwork).
So, your code would look something like this:
networkAddList = (WirelessNetwork,)
Your for loop will then properly iterate over the dictionaries.

python: print values from a dictionary

generic_drugs_mapping={'MORPHINE':[86],
'OXYCODONE':[87],
'OXYMORPHONE':[99],
'METHADONE':[82],
'BUPRENORPHINE':[28],
'HYDROMORPHONE':[54],
'CODEINE':[37],
'HYDROCODONE':[55]}
How do I return 86?
This does not seem to work:
print generic_drugs_mapping['MORPHINE'[0]]
You have a bracket in the wrong place:
print generic_drugs_mapping['MORPHINE'][0]
Your code is indexing the string 'MORPHINE', so it's equivalent to
print generic_drugs_mapping['M']
Since 'M' is not a key in your dictionary, you won't get the results you expect.
The list is the value stored under the key. The part that gets the value out is generic_drugs_mapping['MORPHINE'] so this has the value [86]. Try moving the index outside like this :
generic_drugs_mapping['MORPHINE'][0]

Categories

Resources