'str' object has no attribute 'get' -Learn Python The Hard Way EX39 - python

I am a python beginner. I try to write my hometown city with dictionary after practicing ex39 of Learn Python The Hard Way.
Here are what I wrote:
states = {
'Orangon': 'OR',
'Florida': 'FL',
'California': 'CA',
'New York': 'NY',
'Michigan': 'MI',
}
for state, abbrev in states.items():
print "%s is abbreviated %s" % (state, abbrev)
print states.get('Florida')
print states.get('California')
cities = {
'New Taipei': 'NTP',
'Taipei': 'TP',
'Kaohsiung': 'KHU',
'Taichung': 'TAC',
'Taoyuan': 'TYN',
'Tainan': 'TNA',
'Hsinchu': 'HSC',
'Keelung': 'KLG',
'Chiayi': 'CYI',
'Changhua': 'CHA',
'Pingtung': 'PTG',
'Zhubei': 'ZBI',
'Yuanlin': 'Yln',
'Douliu': 'Dlu',
'Taitung': 'TAT',
'Hualien': 'HUl',
'Toufen': 'TFE',
'Yilan': 'Yln',
'Miaoli': 'Mli',
'Magong': 'Mgn',
}
for cities, abbrev in cities.items():
print "%s is %s" % (cities, abbrev)
print cities.get('Magong')
There is error in the last code:
Traceback (most recent call last):
File "ex39.2.py", line 27, in
print cities.get('Magong')
AttributeError: 'str' object has no attribute 'get'
I don't understand why there is no error in print states.get('California') but there is error in print cities.get('Magong')

In your for loop you are assigning a string to the variable cities:
for cities, abbrev in cities.items():
print "%s is %s" % (cities, abbrev)
thus, after the for loop, cities is no longer a dict, but a string.
Solution: use a different variable in your loop:
for city, abbrev in cities.items():
print "%s is %s" % (city, abbrev)

Related

confused about dictionary created variables

# -*- coding: utf-8 -*-
states = {
'oregon': 'OR',
'florida': 'FL',
'california': 'CA',
'new york': 'NY',
'michigan': 'MI'
}
cities = {
'CA': 'san francisco',
'MI': 'detroit',
'FL': 'jacksonville'
}
cities['NY'] = 'new york'
cities['OR'] = 'portland'
for state, abbrev in states.items(): # add two variables
print "%s is abbreviated %s" % (state, abbrev)
print '-' * 10
for abbrev, city in cities.items():
print "%s has the city %s" % (abbrev, city)
print '-' * 10
for state, abbrev in states.items(): # this is what i'm confusing about
print "%s state is abbreviated %s and has city %s" % (state, abbrev, cities[abbrev])
I just want to know on the questionable line, there are only two variables inputed(state & abbrev), why there could be three variables quoted(state & abbrev & cities[abbrev])?
My guess is that 'abbrev' is being used twice, once in states dict and once in cities dict. So cities[abbrev] means to return the second value of each paired things? Can someone please confirm if my guess is correct?
If that's the case, why do I get a keyerror when I change cities[abbrev] into cities[state]? The error code is: KeyError: 'california'. It should return the first value of each pair.
I am confused on how this is working, can you please help me find a way out?
In your case, states.items() iterates of the key-value pairs, e.g. ('oregon', 'OR'). state will be 'oregon' and abbrev will be 'OR'. What cities[abbrev] does is finding the value of 'OR' in the dictionary cities. In the case of 'OR' that is 'portland'.
If you tried a value that is not in the keys of the dictionary, e.g. banana, then Python would throw a KeyError because the value banana is not a key in that dictionary.
To ensure that a key is present in a dictionary, you can use the in operator.
for state, abbrev in states.items():
# if the value of abbrev (e.g. 'OR') is a value in the cities dictionary
# we know that there is a city in this state. Print it.
if abbrev in cities:
print "%s state is abbreviated %s and has city %s" % (state, abbrev, cities[abbrev])
else:
print "%s is abbreviated %s" % (state, abbrev)

How to get rid of the quote marks from a dict key/value pair?

I have a script that parses a yaml file and extracts key/value pairs and prints them, but I keep getting single quotes in the output.
How do I get rid of the quote marks?
YML Snippet
AsNum:
description: Local AS for BGP global
format: string
type: string
Function from Script
def getVals(dict):
for key,value in dict.items():
#print(keys)
if isDict(value):
if key != "properties" and key != "items":
print(key)
getVals(value)
else:
print("key: ", key, " value: ", value)
Example Output
AsNum
('key: ', 'type', ' value: ', 'string')
('key: ', 'description', ' value: ', 'Local AS for BGP global')
('key: ', 'format', ' value: ', 'string')

How can I get values from dictionary for particular key using python

In this code, I wanted to identify a member with his ID. If the ID exist in the dictionary, I would like to print the fullname of this member
iin = input('Enter your ID :')
dict = {'id' : ['aa', 'bb', 'cc'],
'Firstname' : ['Mark', 'Jamal', 'Van'],
'Lastname' : ['Roch', 'borh', 'nilsa']}
for d in dict:
if inn in d:
print('Hello,', dict[inn])
else :
print('Sorry, you are not a member')
The desired result
Enter your ID : aa
Hello, Mark Roch
Thank you for the help
Please check the below code with comments inline.
iin = input('Enter your ID :')
d = {'id' : ['aa', 'bb', 'cc'],
'Firstname' : ['Mark', 'Jamal', 'Van'],
'Lastname' : ['Roch', 'borh', 'nilsa']}
#Get list of IDs
id_list = d['id']
#Check input in list
if iin in id_list:
#Get index of input from ID list
index = id_list.index(iin)
#Get rest of info
fname = d['Firstname'][index]
lname = d['Lastname'][index]
msg = "Hello, " + fname + " " + lname
print msg
else:
print 'Sorry, you are not a member'
Output :
C:\Users\dinesh_pundkar\Desktop>python b.py
Enter your ID :"aa"
Hello, Mark Roch
C:\Users\dinesh_pundkar\Desktop>python b.py
Enter your ID :"asd"
Sorry, you are not a member
C:\Users\dinesh_pundkar\Desktop>
There's no need to loop over all the items in the dictionary; it would be silly to look for an id in the Firstname and Lastname fields. (And this could produce incorrect results if the entered id happens to be a substring of someone's name.)
What you want is to check if the given id is present in the id list, and if so, use that list position to print the corresponding first and last names:
if iin in dict['id']:
index = dict['id'].index(iin)
print('Hello, %s %s' % (dict['Firstname'][index], dict['Lastname'][index]))
else :
print('Sorry, you are not a member')
Some suggestions:
It might be easier if you arranged your data as a list of dicts each containing a single member, like so:
members = [
{'id': 'aa', 'Firstname': 'Mark', 'Lastname': 'Roch'},
{'id': 'bb', 'Firstname': 'Jamal', 'Lastname': 'borh'},
{'id': 'cc', 'Firstname': 'Van', 'Lastname': 'nilsa'},
]
Don't name your dictionary dict, as that conflicts with a built-in function name.
Building on previous posts
iin = input('Enter your ID :')
dict = {'id' : ['aa', 'bb', 'cc'],
'Firstname' : ['Mark', 'Jamal', 'Van'],
'Lastname' : ['Roch', 'borh', 'nilsa']}
try:
i = dict['id'].index(iin)
print('Hello {0} {1}'.format(dict['Firstname'][i], dict['Lastname'][i])
except ValueError:
print('Sorry, you are not a member')
NOTE: you cannot name a dictionary dict because it conflicts with a keyword.
The working version of the code should be:
my_dict = {'id' : ['aa', 'bb', 'cc'],
'Firstname' : ['Mark', 'Jamal', 'Van'],
'Lastname' : ['Roch', 'borh', 'nilsa']}
iin = input('Enter your ID :')
# Enter your ID :"bb"
try:
my_id = my_dict['id'].index(iin)
print my_dict['Firstname'][my_id], ', ', my_dict['Lastname'][my_id]
except ValueError:
print 'Sorry, you are not a member'
# Jamal , borh
Exlaination/Issues with your code:
for d in dict means for d in dict.keys() which will return ['id', 'FirstName', 'LastName'. In order to iterate over id, you should be doing for d in dict['id']. In fact, iterating over the list itself is not required. To get index of element in ;list, you may simply use list.index(element) function
dict is the built-in class in python. You should never use the keywords
You dictionary structure is itself not correct. By definition, dict means collections of objects and object means similar entities. In this case, Person. Since id is supposed by unique, in am making nested dict with key as id (you may also use list of dict):
{'aa': {'Firstname' : 'Mark',
'Lastname' : 'Roch'},
'bb': {'Firstname' : 'Jamal',
'Lastname' : 'borh'},
'cc': {'Firstname' : 'Van',
'Lastname' : 'nilsa'},
}

How do I work with a nested dictionary's name?

I'm writing a program using dictionaries nested within a list. I want to print the name of each dictionary when looping through the list, but don't know how to do that without calling the entire contents of the dictionary. Here is my code:
sam = {
'food' : 'tortas',
'country' : 'mexico',
'song' : 'Dream On',
}
dave = {
'food' : 'spaghetti',
'country' : 'USA',
'song' : 'Sweet Home Alabama',
}
people = [sam, dave]
for person in people:
for key, value in sorted(person.items()):
print( #person's name +
"'s favorite " + key + " is " + value + ".")
Here is the output:
's favorite country is mexico.
's favorite food is tortas.
's favorite song is Dream On.
's favorite country is USA.
's favorite food is spaghetti.
's favorite song is Sweet Home Alabama.
Everything works, I just need the names of my dictionaries to print. What's the solution?
The (more) correct way of doing this is to construct a dict of dicts instead, such as:
people = {'sam': {'food' : 'tortas',
'country' : 'mexico',
'song' : 'Dream On',
},
'dave': {'food' : 'spaghetti',
'country' : 'USA',
'song' : 'Sweet Home Alabama',
}
}
Then you can simply do the following:
for name, person in people.items():
for key, value in sorted(person.items()):
print(name + "'s favorite " + key + " is " + value + ".")
This will print the following:
dave's favorite country is USA.
dave's favorite food is spaghetti.
dave's favorite song is Sweet Home Alabama.
sam's favorite country is mexico.
sam's favorite food is tortas.
sam's favorite song is Dream On.
As a side note, it is more readable to use string formatting in your print statement:
print("{0}'s favorite {1} is {2}".format(name, key, value))
what you are basically trying to do is printing the name of a variable. Of course, this is not reccomended. If you really want to do this, you should take a look at this post:
How can you print a variable name in python?
What i would do, is to store the name of the dictionary inside of the lists. You could do this by changing 'people = [sam, dave]' to 'people = [["sam", sam], ["dave", dave]]'. This way, person[0] is the name of the person, and person[1] contains the information.
The simplest way is to store the name as a string that maps to the matching variable identifier:
people = {'sam':sam, 'dave':dave}
for name, person in people.items():
for key, value in sorted(person.items()):
print(name + "'s favorite " + key + " is " + value + ".")
If you really don't like the idea of typing each name twice, you could 'inline' the dictionaries:
people = {
'sam':{
'food' : 'tortas',
'country' : 'mexico',
'song' : 'Dream On',
},
'dave':{
'food' : 'spaghetti',
'country' : 'USA',
'song' : 'Sweet Home Alabama',
}
}
Finally, if you can rely on those variables being in the global namespace and are more concerned with just making it work than purity of practice, you can find them this way:
people = ['sam', 'dave']
for name in people:
person = globals()[name]
for key, value in sorted(person.items()):
print(name + "'s favorite " + key + " is " + value + ".")
Values in a list aren't really variables any more. They aren't referred to by a name in some namespace, but by an integer indicating their offsets from the front of the list (0, 1, ...).
If you want to associate each dict of data with some name, you have to do it explicitly. There are two general options, depending on what's responsible for tracking the name: the collection of people, or each person in the collection.
The first and easiest is the collections.OrderedDict --- unlike the normal dict, it will preserve the order of the people in your list.
from collections import OrderedDict
sam = {
'food': 'tortas',
'country': 'Mexico',
'song': 'Dream On',
}
dave = {
'food': 'spaghetti',
'country': 'USA',
'song': 'Sweet Home Alabama',
}
# The OrderedDict stores each person's name.
people = OrderedDict([('Sam', sam), ('Dave', dave)])
for name, data in people.items():
# Name is a key in the OrderedDict.
print('Name: ' + name)
for key, value in sorted(data.items()):
print(' {0}: {1}'.format(key.title(), value))
Alternatively, you can store each person's name in his or her own dict... assuming you're allowed to change the contents of those dictionaries. (Also, you wouldn't want to add anything to the data dictionary that would require you to change / update the data more than you already do. Since most people change their favorite food or song much more often than they change their name, this is probably safe.)
sam = {
# Each dict has a new key: 'name'.
'name': 'Sam',
'food': 'tortas',
'country': 'Mexico',
'song': 'Dream On',
}
dave = {
'name': 'Dave',
'food': 'spaghetti',
'country': 'USA',
'song': 'Sweet Home Alabama',
}
people = [sam, dave]
for data in people:
# Name is a value in the dict.
print('Name: ' + data['name'])
for key, value in sorted(data.items()):
# Have to avoid printing the name again.
if 'name' != key:
print(' {0}: {1}'.format(key.title(), value))
Note that how you print the data depends on whether you store the name in the collection (OrderedDict variant), or in each person's dict (list variant).
Thanks for the great input. This program is for a practice example in "Python Crash Course" by Eric Matthes, so the inefficient "dictionaries inside list" format is intentional. That said, I got a lot out of your comments, and altered my code to get the desired output:
sam = {
#Added a 'name' key-value pair.
'name' : 'sam',
'food' : 'tortas',
'country' : 'mexico',
'song' : 'Dream On',
}
dave = {
'name' : 'dave',
'food' : 'spaghetti',
'country' : 'USA',
'song' : 'Sweet Home Alabama',
}
people = [sam, dave]
for person in people:
for key, value in sorted(person.items()):
#Added if statement to prevent printing the name.
if key != 'name':
print(person['name'].title() + "'s favorite " + key + " is " + value + ".")
#Added a blank line at the end of each for loop.
print('\n')
Here is the output:
Sam's favorite country is mexico.
Sam's favorite food is tortas.
Sam's favorite song is Dream On.
Dave's favorite country is USA.
Dave's favorite food is spaghetti.
Dave's favorite song is Sweet Home Alabama.
Thanks again, all who provided insightful answers.

Extract resulted list data to a xml file in python

How can I extract my resulted list data to an xml file?
My resulted list is given below:
week=[{'item': Electrelane, 'weight': 140}, {'item': Kraftwerk, 'weight': 117},{'item': The Flaming Lips, 'weight': 113}]
Since you don't provide any information on how you want to format your XML, i just invented my own notation.
week=[{'item': 'Electrelane', 'weight': 140}, {'item': 'Kraftwerk', 'weight': 117},{'item': 'The Flaming Lips', 'weight': 113}]
print "<?xml version='1.0' ?>"
print "<week>"
for day in week:
print " <day>"
for key, value in day.items():
print " <%s>%s</%s>" % (key, value, key)
print " </day>"
print "</week>"
EDIT
To print to console, iterate over items in a similar way but change the output (by the print commands)
# enumerate the days in the week
for i, day in enumerate(week):
print "day %d" % i
# show values in sorted order
for key in sorted(day):
print " - %s\t: %s" % (key, day[key])
You can trivially adjust this to your needs.
Here's some code that uses xml.dom.minidom to build up the XML document.
week=[{'item': 'Electrelane', 'weight': 140}, {'item': 'Kraftwerk', 'weight': 117},{'item': 'The Flaming Lips', 'weight': 113}]
from xml.dom.minidom import getDOMImplementation
impl = getDOMImplementation()
document = impl.createDocument(None, "week", None)
week_element = document.documentElement
for entry in week:
node = document.createElement("entry")
for attr,value in entry.iteritems():
node.setAttribute(attr,str(value))
week_element.appendChild(node)
print document.toprettyxml()
Produces:
<?xml version="1.0" ?>
<week>
<entry item="Electrelane" weight="140"/>
<entry item="Kraftwerk" weight="117"/>
<entry item="The Flaming Lips" weight="113"/>
</week>

Categories

Resources