Dictionary to JSON object conversion - python

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)]

Related

Optimal code to check and append an item in a list if present in a list of dictionaries

These are my inputs, pretty-printed for better readability
input1 = [{
"ID": "1",
"SequenceNum": 1
},
{
"ID": "2",
"SequenceNum": 2
},
{
"ID": "3",
"SequenceNum": 3
},
{
"ID": "4",
"SequenceNum": 4
}]
input2 = ['4', '1']
The values contained in input2 are basically the values of the 'ID' key seen in input1
The output will be a list of dictionaries where input1[index]['ID'] == input2[index_element].
Expected output -> [{"ID": "4","SequenceNum": 4},{"ID": "1","SequenceNum": 1}]
I have solved this using the following lines of code:
match_list = []
for idx,val in enumerate(input1):
match_list.append(val['ID'])
return_list = []
for idx,val in enumerate(input2):
if val in match_list:
get_idx = match_list.index(val)
return_list.append(input1[get_idx])
While it works it doesn't feel like the most optimal nor the cleanest way to write code. I apologize for the basic question, I am not a very experienced programmer.
IIUC, you could do:
s = set(input2)
res = [d for d in input1 if d["ID"] in s]
print(res)
Output
[{'ID': '1', 'SequenceNum': 1}, {'ID': '4', 'SequenceNum': 4}]
This has an expected linear complexity.
If the order with respect to input2 needs to be kept, you could do:
lookup = {d["ID"]: d for d in input1}
res = [lookup[i] for i in input2 if i in lookup]
print(res)
This also has an expected linear complexity.

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

Ordered Dict of columns to Rows for CSV?

Suppose I have an ordered dict in the following format:
{ 'col0': [ 'a','b',...,'z' ],
'col1': [ ... ],
...
}
However, the csv library, when writing a dictionary out to a file, expects a list of rows:
{ 'col0': 'a', 'col1': 'b' }
{ 'col0': 'c', 'col1': 'd' }
How does one transition from an OrderedDict as described above to a set of values corresponding to the format that csv expects in the best possible way? (i.e., simple and fast)
This might get you the expected output:
func = lambda y: {'col'+str(i): y[i] for i in range(len(y))}
x = {func(dict(i)) for i in dict}
You can use this to convert dict into a csv file:
import csv
dict = {'a': '1', 'b': 2, 'c': '3'}
with open('data.csv', 'w') as f:
for key in dict.keys():
f.write("%s, %s\n" % (key, dict[key]))
Answer:
csv.writerow(ordered_dict.keys())
csv.writerows(zip(*ordered_dict.values()))

Sorting a Dictionary by Nested Key

Consider a dict of the following form:
dic = {
"First": {
3: "Three"
},
"Second": {
1: "One"
},
"Third": {
2:"Two"
}
}
I would like to sort it by the nested dic key (3, 1, 2)
I tried using the lambda function in the following manner but it returns a "KeyError: 0"
dic = sorted(dic.items(), key=lambda x: x[1][0])
The expected output would be:
{
"Second": {
1: "One"
},
"Third": {
2: "Two"
},
"First": {
3:"Three"
}
}
In essence what I want to know is how to designate a nested key independently from the main dictionary key.
In the lambda function, x is a key-value pair, x[1] is the value, which is itself a dictionary. x[1].keys() is its keys, but it needs to be turned into a list if you want to get its one and only item by its index. Thus:
sorted(dic.items(), key = lambda x: list(x[1].keys())[0])
which evaluates to:
[('Second', {1: 'One'}), ('Third', {2: 'Two'}), ('First', {3: 'Three'})]
dic = {'First': {3: 'Three'}, 'Second': {1: 'One'}, 'Third': {2: 'Two'}}
sorted_list = sorted(dic.items(), key=lambda x:list(x[1].keys())[0])
sorted_dict = dict(sorted_list)
print(sorted_dict)
You need to get the keys for the nested dictionary first and then convert them into list and sort over its first index. You will get a sorted list. All you need to convert this list to dictionary using dict(). I hope that helps. This snippet works for python3.

Dictionaries store pairs. Who stores triples?

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']

Categories