Dictionaries store pairs. Who stores triples? - python

We would use a dictionary to store for example:
a={"breakfast":"banana","lunch":"fish","dinner":"soup"}
What would your approach be if you want to add the time attribute alongside every key-value set. Of course not:
a={"8AM":"breakfast":"banana","2PM":"lunch":"fish","8PM":"dinner":"soup"}
Then I would like to use one or more keys to access a value.
Maybe by doing a trick with lists?

You can use a tuple as a dictionary key:
a = {("8AM", "breakfast"): "banana",
("2PM", "lunch"): "fish",
("8PM", "dinner"): "soup",
}

Use a dictionary with a tuple as the key:
>>> a={("8AM","breakfast"):"banana",("2PM","lunch"):"fish",("8PM","dinner"):"soup"}
>>> a["8AM","breakfast"]
'banana'
Or if you want to look up the time and the food using just the meal name:
>>> a={"breakfast":("8AM","banana"),"lunch":("2PM","fish"),"dinner":("8PM","soup")}
>>> a["breakfast"]
('8AM', 'banana')

Since you want to use a dictionary and possibly lists, I would recommend determining what your "primary key" is and creating a nested structure like this:
a = {
'breakfast': {
'time': "8AM",
'items': ['banana', 'yogurt']
},
'lunch': {
'time': '2PM',
'items': ['fish', 'tartar sauce']
},
'dinner': {
'time': '8PM',
'items': ['soup', 'salad']
}
}
The time for each meal is variable, but we all know we eat breakfast, lunch, and dinner (or at least we should). Doing this you can then determine the time and items that were consumed:
a['breakfast']['time']
'8AM'
a['breakfast']['items']
['banana', 'yogurt']

a = {"8AM":{"breakfast":"banana"},"2PM":{"lunch":"fish"},"8PM":{"dinner":"soup"}}
Using:
>>>a['8AM']['breakfast']
'banana'
Other:
def r(_d,_target):
result = []
for k, v in _d.items():
if(k == _target):
if type(v) == type({}):
for x in v.keys():
result.append(v[x])
else:
result.append(v)
if type(v) == type({}):
r2 = r(v,_target)
if len(r2) > 0:
for l in r2:
result.append(l)
return result
>>> r(a,"breakfast")
['banana']
>>> r(a,"8AM")
['banana']
>>> r(a,"dinner")
['soup']

Related

Best practice/way to get value where id = something on a list of dictionaries

I have the following list of dictionaries:
[{'id': 360004373520, 'value': something1}, {'id': 360004411159, 'value': something2}, {'id': 360004373540, 'value': something}]
I would like to get the value where id = xxxxxxxxxxxx.
Which would be the fastest way?
One possible solution is to use next() built-in method:
lst = [
{"id": 360004373520, "value": "something1"},
{"id": 360004411159, "value": "something2"},
{"id": 360004373540, "value": "something"},
]
to_search = 360004411159
value = next(d["value"] for d in lst if d["id"] == to_search)
print(value)
Prints:
something2
Or: If you search multiple times, it's worth considering transforming the list to dictionary:
to_search = 360004411159
dct = {d["id"]: d["value"] for d in lst}
print(dct[to_search])
This is one possible solution:
for key in lst:
if key['id']=='xxxxxx':
#do something

Making a new list of dictionary values whose keys match items in a seperate list

This dictionary stores the farm animals as the key and their location as the value.
id_name_dict = {
'cat': 'barn', 'dog': 'field', 'chicken': 'coop',
'sheep': 'pasture', 'horse': 'barn', 'cow': 'barn'
}
This list stores the names of the farm animals whose location I want to know
wanted_farm_animals = ['cat,', 'dog', 'horse']
The desired output is a new list with the wanted_farm_animals location
n = ['barn', 'field', 'barn']
Here is the code I tried to do this
n = []
for animal, location in id_name_dict.items():
for a in wanted_farm_animals:
if a == animal:
n.append(location)
print(n)
However, the output is not complete. It is only
['field', 'barn']
How do I get the correct desired output?
How about simple list comprehension?
id_name_dict = {
'cat': 'barn', 'dog': 'field', 'chicken': 'coop',
'sheep': 'pasture', 'horse': 'barn', 'cow': 'barn'
}
wanted_farm_animals = ['cat', 'dog', 'horse']
result = [v for k,v in id_name_dict.items() if k in wanted_farm_animals]
# ['barn', 'field', 'barn']
You can map the wanted_farm_animals list to the dict.get method bound to the id_name_dict dict:
n = list(map(id_name_dict.get, wanted_farm_animals))
By using the dict.get method you would get a default value of None instead of a KeyError exception for an item that's in the wanted_farm_animals list but not in the keys of the id_name_dict dict.

Dictionary to JSON object conversion

I have 2 long lists (extracted from a csv) both of the same index length.
Example:
l1 = ['Apple','Tomato','Cocos'] #name of product
l2 = ['1','2','3'] #some id's
I made my dictionary with this method:
from collections import defaultdict
d = defaultdict(list)
for x in l1:
d['Product'].append(x)
for y in l2:
d['Plu'].append(y)
print d
This will output:
{'Product': ['Apple', 'Tomato', 'Cocos'], 'Plu': ['1', '2', '3']}
(Product and Plu are my wanted keys)
Now I've tried to import this to a JavaScript Object like this:
import json
print(json.dumps(d, sort_keys=True, indent=4))
This will output:
{
"Plu": [
"1",
"2",
"3"
],
"Product": [
"Apple",
"Tomato",
"Cocos"
]
}
But my desired output is this:
{
Product:'Apple',
Plu:'1'
},
{
Product:'Tomato',
Plu:'2'
},
{
Product:'Cocos',
Plu:'3'
}
I will later use that to insert values in a MongoDB. What will I have to change in my json.dump (or in my dict?) in order to get a desired output? Also is there a way to save the output in a txt file? (since I will have a big code).
Rather than using a defaultdict (which doesn't buy you anything in this case), you're better off zipping the lists and creating a dict from each pair:
[{'Product': product, 'Plu': plu} for product, plu in zip(l1, l2)]

Get list of all second-order keys in nested dictionary

From my dictionary of dictionaries I would like to receive a list of all second-order keys.
myDict = {
u'A': {'1998': u'ATLANTA'},
u'B': {'1999': u'MANNHEIM'},
u'C': {'2000': u'BERLIN'},
u'D': {'1998': u'CHICAGO', '1999': u'PRINCETON'},
u'E': {'2000': u'LOUISIANA'},
u'F': {'1998': u'NEW YORK', '1999': u'NEW YORK'}
}
I do
years = []
for author in author_aff_dict:
years.extend(author_aff_dict[author].keys())
print uniqfy(years)
where uniqfy() is from http://www.peterbe.com/plog/uniqifiers-benchmark:
def uniqfy(seq, idfun=None):
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result
Everything works as expected (i.e. years is ['1998', '2000', '1999']), but I am sure there must be a better/shorter way in getting a list of all keys of the nested dictionaries.
You can use a set comprehension :
>>>s= {j for i in myDict.values() for j in i}
set(['1999', '1998', '2000'])
Then if you just want a list object you can use list() to convert the set to list.
>>> list(s)
['1999', '1998', '2000']
>>> myList = []
>>> for i in myDict.values():
... for j in i.keys():
... if j not in myList: myList.append(j)
... else: continue
...
>>> myList
['1998', '2000', '1999']
edit: i'd prefer #Kasra's answer :)

Extract values by key from a nested dictionary

Given this nested dictionary, how could I print all the "phone" values using a for loop?
people = {
'Alice': {
'phone': '2341',
'addr': '87 Eastlake Court'
},
'Beth': {
'phone': '9102',
'addr': '563 Hartford Drive'
},
'Randy': {
'phone': '4563',
'addr': '93 SW 43rd'
}
for d in people.values():
print d['phone']
Loop over the values and then use get() method, if you want to handle the missing keys, or a simple indexing to access the nested values. Also, for the sake of optimization you can do the whole process in a list comprehension :
>>> [val.get('phone') for val in people.values()]
['4563', '9102', '2341']
Using a list comprehension
>>> [people[i]['phone'] for i in people]
['9102', '2341', '4563']
Or if you'd like to use a for loop.
l = []
for person in people:
l.append(people[person]['phone'])
>>> l
['9102', '2341', '4563']

Categories