I'm trying to set a dictionary that will allow me to loop through 3 levels. For example:
Level 1: Meats, Non-Meats
Level 2: Fruit, Vegetable, Pig, Cow
Level 3: Apple, Oranges, Broccoli, Carrots, Bacon, Ham, Ribs, Steak
The dictionary I have attempted is as follows:
X = {
"Meats":{
"Pig":[["Bacon"], ["Ham"]],
"Cow":[["Ribs"], ["Steak"]]
},
"Non-Meats":{
"Fruit":[["Apple"], ["Oranges"]],
"Vegetable":[["Broccoli"], ["Carrots"]]
}
}
Any advice on how to handle this would be appreciated.
What you're looking to do is create a nested dictionary.
One thing that may help you understand the structure you're creating is proper formatting. There's a standard for formatting called PEP8, but as long as you're consistent, you can use whatever style you want.
X = {
"Meats": {
"Pig": [
["Bacon"], ["Ham"]
],
"Cow": [
["Ribs"], ["Steak"]
]
},
"Non-Meats": {
"Fruit": [
["Apple"], ["Oranges"]
],
"Vegetable": [
["Broccoli"], ["Carrots"]
]
}
}
Does this formatting make the structure easier to read? It seems to me that the brackets around each inner item are unnecessary, as they're already inside part of a list
If we rewrite the Vegetable item of the 'non-meats' dictionary item without those inner square brackets, it looks like this:
"Vegetable": [
"Broccoli", "Carrots"
]
Then you could get a list of the vegatables like so:
veggies = x['Non-Meats']['Vegetable']
The variable 'veggies' is now an iterable list. Printing that list would result in something like this:
['Broccoli', 'Carrots']
What you need to solve such a problem is work step by step through your dictionary and figure out what exactly you need to iterate through.
Step one:
How will you iterate through the top-level dictionary keys?
for key in X:
do something
Step two:
Q: For each key, what do you have to iterate through?
Answer: another dict. So, we have including the previous step:
for key in X:
for key_two in X[key]:
do something
Step 3:
Q: What do you finally have within each of these dicts?
Answer: list of lists (e.g. [["Bacon"]]). I'm not sure why each of these is a list, you could just make them strings. For example, {"Pig": ["Bacon", "Ham"]}. However, for what you have, we get:
for key in X:
for key_two in X[key]:
for food in X[key][key_two]:
print food # If you want to print without the list, it'd be either a final nested loop or "print food[0]"
Related
#python
pets=[] #created an empty list
d={'owner_name': 'holland',
'pet_kind':'mischieveous',
}
d={'owner_name': 'rowman',
'pet_kind':'smart',
}
d={'owner_name': 'clark',
'pet_kind':'happy'
}
d={'owner_name': 'shaun',
'pet_kind':'shy',
}
d={'owner_name': 'seaman',
'pet_kind':'intellectual',
}
pets=[pets.append(pet) for pet in d.items()]
print(pets)
output is showing [None, None] , I believe it should show the dictionary #appended in pets but it is not please help a newbie here .. please
for pet in d.items():
pets.append(pet)
print(pets)
also if i use the for loop the second way it still gives me only the last dictionary as answer, the seaman and intellectual one, i am hopeful to learn this lang please help
here i have included the second way above please check
What are you trying to achieve? Is this just homework?
You can simply create a list of dicts to get the same result:
pets = [{'owner_name': 'holland', 'pet_kind':'mischieveous'},
{'owner_name': 'rowman', 'pet_kind':'smart'},
{'owner_name': 'clark', 'pet_kind':'happy'},
{'owner_name': 'shaun', 'pet_kind':'shy'},
{'owner_name': 'seaman', 'pet_kind':'intellectual'}]
This code would do the work:
d = {
"owner_name": "seaman",
"pet_kind": "intellectual",
}
pets=[pet for pet in d.items()]
print(pets)
the second way you said has a problem that is because you named all your variables "d". they overwrite each other.
Firstly, the list comprehension:
pets = [pets.append(pet) for pet in d.items()]
This syntax collects the results of the method call pets.append(...) in a list, then assigns it to the variable pets. However, pets.append(...) does not return anything — it modifies the list in place — so that will collect a list of None values as returned from each call of the method.
The method will append it to pets in-place, but then the assignment operator will overwrite pets with the list of None values, which you're seeing.
Secondly, the assignments:
d = {
'owner_name': 'holland',
'pet_kind': 'mischievous',
}
d = {
'owner_name': 'rowman',
'pet_kind': 'smart',
}
...
These will assign different values to the same variable d, just like writing:
x = 1
x = 2
...
Finally, the .items() method
for pet in d.items():
This method is applicable to a dictionary, not a list; it turns that dictionary into a list of pairs, so within the loop, the variable pet will have the value ('owner_name', 'seaman') the first time through the loop and then ('pet_kind', 'intellectual') the second time through the loop.
As a side-note, it's often more convenient to "unpack" those pairs into a pair of variables, like this:
for key, value in d.items():
I am pretty new to Python (coming from a Java background) so was wondering if someone would have any advice on a data structure design question. I need to create a data structure with default values that would look something like this:
[
(Name=”name1”, {id=1, val1=”val1”} ),
(Name=”name2”, {id=2, val1=”val2”} )
]
i.e a list of tuples where each tuple consists of one string value (Name) and a dictionary of values.
The first piece of functionality I need is to be able to add to or override the above data structure with additional details e.g:
[
(Name=”name2”, {id=2, val1=”new value”} ) ,
(Name=”name2”, {id=3, val1=”another value”} ) ,
(Name=”name3”, {id=3, val1=”val3”} )
]
Which would ultimately result in a final data structure that looks like this:
[
(Name=”name1”, {id=1, val1=”val1”} ),
(Name=”name2”, {id=2, val1=”new value”} ) ,
(Name=”name2”, {id=3, val1=”another value”} ) ,
(Name=”name3”, {id=3, val1=”val3”} )
]
The second piece of functionality I need is to be able to access each tuple in the list according to the id value in the dictionary i.e
Get me tuple where name = “name2” and id=”3” .
Could anybody give me their opinions on how best this could be implemented in Python?
Thanks!
The namedtuple is closest to what you wrote but as others have said, there may be better designs for what you want.
You should try using dictionaries may be.
A dictionary is mutable and is another container type that can store any number of Python objects, including other container types. Dictionaries consist of pairs (called items) of keys and their corresponding values.
Python dictionaries are also known as associative arrays or hash tables. The general syntax of a dictionary is as follows:
dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
You can create dictionary in the following way as well:
dict1 = { 'abc': 456 };
dict2 = { 'abc': 123, 98.6: 37 };
Each key is separated from its value by a colon (:), the items are separated by commas, and the whole thing is enclosed in curly braces. An empty dictionary without any items is written with just two curly braces, like this: {}.
Keys are unique within a dictionary while values may not be. The values of a dictionary can be of any type, but the keys must be of an immutable data type such as strings, numbers, or tuples.
Accessing Values in Dictionary:
To access dictionary elements, you can use the familiar square brackets along with the key to obtain its value. Following is a simple example:
#!/usr/bin/python
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};
print "dict['Name']: ", dict['Name'];
print "dict['Age']: ", dict['Age'];
When the above code is executed, it produces the following result:
dict['Name']: Zara
dict['Age']: 7
Source: http://www.tutorialspoint.com/python/python_dictionary.htm
First, here is a sample JSON feed that I want to read in Python 2.7 with either simplejson or the built in JSON decoder. I am loading the .json file in Python and then searching for a key like "Apple" or "Orange" and when that key is found, I want to bring in the information for it like the types and quantities.
Right now there is only 3 items, but I want to be able to search one that may have up to 1000 items. Here is the code:
{
"fruits": [
{
"Apple": [
{
"type": "Gala",
"quant": 5
},
{
"type": "Honeycrisp",
"quant": 10
},
{
"type": "Red Delicious",
"quant": 4
}
]
},
{
"Banana": [
{
"type": "Plantain",
"quant": 5
}
]
},
{
"Orange": [
{
"type": "Blood",
"quant": 3
},
{
"type": "Navel",
"quant": 20
}
]
}
]
}
My sample Python code is as follows:
import simplejson as json
# Open file
fjson = open('/home/teg/projects/test/fruits.json', 'rb')
f = json.loads(fjson.read())
fjson.close()
# Search for fruit
if 'Orange' in json.dumps(f):
fruit = f['fruits']['Orange']
print(fruit)
else:
print('Orange does not exist')
But whenever I test it out, it gives me this error:
TypeError: list indices must be integers, not str
Was it wrong to have me do a json.dumps and instead should I have just checked the JSON feed as-is from the standard json.loads? I am getting this TypeError because I am not specifying the list index, but what if I don't know the index of that fruit?
Do I have to first search for a fruit and if it is there, get the index and then reference the index before the fruit like this?
fruit = f['fruits'][2]['Orange']
If so, how would I get the index of that fruit if it is found so I could then pull in the information? If you think the JSON is in the wrong format as well and is causing this issue, then I am up for that suggestion as well. I'm stuck on this and any help you guys have would be great. :-)
Your f type is list, it's a list of dictionary's with sub dictionary.
if 'Orange' in json.dumps(f): Will iterate the list and look at each item for Orange.
The problem is that f['fruits'] is a list so it expects an int number (place)
and not a dictionary key like ['Orange']
I think you should check your structure like #kindall said, if you still want to extract Orange this code will do the trick:
for value in f['fruits']:
if 'Orange' in value:
print value['Orange']
The problem is that the data structure has a list enclosing the dictionaries. If you have any control over the data source, that's the place to fix it. Otherwise, the best course is probably to post-process the data after parsing it to eliminate these extra list structures and merge the dictionaries in each list into a single dictionary. If you use an OrderedDict you can even retain the ordering of the items (which is probably why the list was used).
The square bracket in the line "fruits": [ should tell you that the item associated with fruits is (in Python parlance) a list rather than a dict and so cannot be indexed directly with a string like 'Oranges'. It sounds like you want to create a dict of fruits instead. You could do this by reformatting the input.
Or, if the input format is fixed: each item in your fruits list currently has a very specific format. Each item is a dict with exactly one key, and those keys are not duplicated between items. If those rules can be relied upon, it's pretty easy to write a small search routine—or the following code will convert a list-of-dicts into a dict:
fruits = dict(sum([x.items() for x in f['fruits']], []))
print fruits['Orange']
I'm pretty new to Python, so I'm having a hard time even coming up with the proper jargon to describe my issue.
Basic idea is I have a dict that has the following structure:
myDict =
"SomeMetric":{
"day":[
{"date": "2013-01-01","value": 1234},
{"date": "2013-01-02","value": 5678},
etc...
I want to pull out the "value" where the date is known. So I want:
myDict["SomeMetric"]["day"]["value"] where myDict["SomeMetric"]["day"]["date"] = "2013-01-02"
Is there a nice one-line method for this without iterating through the whole dict as my dict is much larger, and I'm already iterating through it, so I'd rather not do nested iteritems.
Generator expressions to the resque:
next(d['value']
for d in myDict['SomeMetric']['day']
if d['date'] == "2013-01-02")
So, loop over all day dictionaries, and find the first one that matches the date you are looking for. This loop stops as soon as a match is found.
Do you have control over your data structure? It seems to be constructed in such a way that lends itself to sub-optimal lookups.
I'd structure it as such:
data = { 'metrics': { '2013-01-02': 1234, '2013-01-01': 4321 } }
And then your lookup is simply:
data['metrics']['2013-01-02']
Can you change the structure? If you can, you might find it much easier to change the day list to a dictionary which has dates as keys and values as values, so
myDict = {
"SomeMetric":{
"day":{
"2013-01-01": 1234,
"2013-01-02": 5678,
etc...
Then you can just index into it directly with
myDict["SomeMetric"]["day"]["2013-01-02"]
Consider a dict like
mydict = {
'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'} }
How do I access for instance a particular element of this dictionary?
for instance, I would like to print the first element after some formatting the first element of Apple which in our case is 'American' only?
Additional information
The above data structure was created by parsing an input file in a python function. Once created however it remains the same for that run.
I am using this data structure in my function.
So if the file changes, the next time this application is run the contents of the file are different and hence the contents of this data structure will be different but the format would be the same.
So you see I in my function I don't know that the first element in Apple is 'American' or anything else so I can't directly use 'American' as a key.
Given that it is a dictionary you access it by using the keys. Getting the dictionary stored under "Apple", do the following:
>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}
And getting how many of them are American (16), do like this:
>>> mydict["Apple"]["American"]
'16'
If the questions is, if I know that I have a dict of dicts that contains 'Apple' as a fruit and 'American' as a type of apple, I would use:
myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'} }
print myDict['Apple']['American']
as others suggested. If instead the questions is, you don't know whether 'Apple' as a fruit and 'American' as a type of 'Apple' exist when you read an arbitrary file into your dict of dict data structure, you could do something like:
print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]
or better yet so you don't unnecessarily iterate over the entire dict of dicts if you know that only Apple has the type American:
if 'Apple' in myDict:
if 'American' in myDict['Apple']:
print myDict['Apple']['American']
In all of these cases it doesn't matter what order the dictionaries actually store the entries. If you are really concerned about the order, then you might consider using an OrderedDict:
http://docs.python.org/dev/library/collections.html#collections.OrderedDict
As I noticed your description, you just know that your parser will give you a dictionary that its values are dictionary too like this:
sampleDict = {
"key1": {"key10": "value10", "key11": "value11"},
"key2": {"key20": "value20", "key21": "value21"}
}
So you have to iterate over your parent dictionary. If you want to print out or access all first dictionary keys in sampleDict.values() list, you may use something like this:
for key, value in sampleDict.items():
print value.keys()[0]
If you want to just access first key of the first item in sampleDict.values(), this may be useful:
print sampleDict.values()[0].keys()[0]
If you use the example you gave in the question, I mean:
sampleDict = {
'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'}
}
The output for the first code is:
American
Indian
And the output for the second code is:
American
EDIT 1:
Above code examples does not work for version 3 and above of python; since from version 3, python changed the type of output of methods keys and values from list to dict_values. Type dict_values is not accepting indexing, but it is iterable. So you need to change above codes as below:
First One:
for key, value in sampleDict.items():
print(list(value.keys())[0])
Second One:
print(list(list(sampleDict.values())[0].keys())[0])
I know this is 8 years old, but no one seems to have actually read and answered the question.
You can call .values() on a dict to get a list of the inner dicts and thus access them by index.
>>> mydict = {
... 'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
... 'Grapes':{'Arabian':'25','Indian':'20'} }
>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}
>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']
As a bonus, I'd like to offer kind of a different solution to your issue. You seem to be dealing with nested dictionaries, which is usually tedious, especially when you have to check for existence of an inner key.
There are some interesting libraries regarding this on pypi, here is a quick search for you.
In your specific case, dict_digger seems suited.
>>> import dict_digger
>>> d = {
'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'}
}
>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None
You can use mydict['Apple'].keys()[0] in order to get the first key in the Apple dictionary, but there's no guarantee that it will be American. The order of keys in a dictionary can change depending on the contents of the dictionary and the order the keys were added.
You can't rely on order of dictionaries, but you may try this:
mydict['Apple'].items()[0][0]
If you want the order to be preserved you may want to use this:
http://www.python.org/dev/peps/pep-0372/#ordered-dict-api
Simple Example to understand how to access elements in the dictionary:-
Create a Dictionary
d = {'dog' : 'bark', 'cat' : 'meow' }
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))
Explore more about Python Dictionaries and learn interactively here...
Few people appear, despite the many answers to this question, to have pointed out that dictionaries are un-ordered mappings, and so (until the blessing of insertion order with Python 3.7) the idea of the "first" entry in a dictionary literally made no sense. And even an OrderedDict can only be accessed by numerical index using such uglinesses as mydict[mydict.keys()[0]] (Python 2 only, since in Python 3 keys() is a non-subscriptable iterator.)
From 3.7 onwards and in practice in 3,6 as well - the new behaviour was introduced then, but not included as part of the language specification until 3.7 - iteration over the keys, values or items of a dict (and, I believe, a set also) will yield the least-recently inserted objects first. There is still no simple way to access them by numerical index of insertion.
As to the question of selecting and "formatting" items, if you know the key you want to retrieve in the dictionary you would normally use the key as a subscript to retrieve it (my_var = mydict['Apple']).
If you really do want to be able to index the items by entry number (ignoring the fact that a particular entry's number will change as insertions are made) then the appropriate structure would probably be a list of two-element tuples. Instead of
mydict = {
'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'} }
you might use:
mylist = [
('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
('Grapes', {'Arabian': '25', 'Indian': '20'}
]
Under this regime the first entry is mylist[0] in classic list-endexed form, and its value is ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). You could iterate over the whole list as follows:
for (key, value) in mylist: # unpacks to avoid tuple indexing
if key == 'Apple':
if 'American' in value:
print(value['American'])
but if you know you are looking for the key "Apple", why wouldn't you just use a dict instead?
You could introduce an additional level of indirection by cacheing the list of keys, but the complexities of keeping two data structures in synchronisation would inevitably add to the complexity of your code.
With the following small function, digging into a tree-shaped dictionary becomes quite easy:
def dig(tree, path):
for key in path.split("."):
if isinstance(tree, dict) and tree.get(key):
tree = tree[key]
else:
return None
return tree
Now, dig(mydict, "Apple.Mexican") returns 10, while dig(mydict, "Grape") yields the subtree {'Arabian':'25','Indian':'20'}. If a key is not contained in the dictionary, dig returns None.
Note that you can easily change (or even parameterize) the separator char from '.' to '/', '|' etc.
mydict = {
'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'} }
for n in mydict:
print(mydict[n])