I am trying to create "child,parent" dictionary from my dictionary. How can i achieve that?
Here is my dict:
{"Sıdıka":[{"Aziz":[{"Ahmet":[{"Kuzey":[]}],"Öznur":[{"Elif":[]},{"Yiğit":[]}],"İlknur":[{"Nurullah":[]},{"Büşra":[]}],"İlker":[{"Melih":[]}]}]}]}
Left to right ancestors are growing. Sıdıka is grand grand grand grand mother, aziz is her son. And "ahmet, öznur,ilknur,ilker" are "aziz"s children etc. etc.
I want a dictionary something like this:
{'Sıdıka':[{'Aziz':[{'Ahmet':[{'Kuzey':[]}],'Öznur':[{'Elif':[]},{'Yiğit':[]}],'İlknur':[{'Nurullah':[]},{'Büşra':[]}],{'İlker':[{'Melih':[]}]}]
I think i need a very good algorithm for this. Any help?
You can use recursion for the task:
d = {
"Sıdıka": ["Aziz"],
"Aziz": ["Ahmet", "Öznur", "İlknur", "İlker"],
"Ahmet": ["Kuzey"],
"Öznur": ["Elif", "Yiğit"],
"İlknur": ["Nurullah", "Büşra"],
"İlker": ["Melih"],
}
def get_tree(root):
return {root: [get_tree(v) for v in d.get(root, [])]}
print(get_tree("Sıdıka"))
Prints:
{
"Sıdıka": [
{
"Aziz": [
{"Ahmet": [{"Kuzey": []}]},
{"Öznur": [{"Elif": []}, {"Yiğit": []}]},
{"İlknur": [{"Nurullah": []}, {"Büşra": []}]},
{"İlker": [{"Melih": []}]},
]
}
]
}
Related
I have a list of dicts that looks like this:
{
"Player_Name":"Byeong-Hun An",
"Tournament":[
{
"Name":"Arnold Palmer Invitational presented by Mastercard",
"Points":"32.80",
"Salary":"10300.00"
}
]
},
{
"Player_Name":"Byeong-Hun An",
"Tournament":[
{
"Name":"Different",
"Points":"18.80",
"Salary":"10400.00"
}
]
}
and I want this:
[
{
"Player_Name":"Byeong-Hun An",
"Tournament":[
{
"Name":"Arnold Palmer Invitational presented by Mastercard",
"Points":"32.80",
"Salary":"10300.00"
},
{
"Name":"Different",
"Points":"18.80",
"Salary":"10400.00"
}
]
}
]
I've tried collections, but it doesn't do exactly what I'm wanting. I essentially want to take every single player and combine all the tournament objects into one so each player has one object instead of each event having its own object.
Here's my code
import json
import numpy as np
import pandas as pd
from collections import Counter
# using json open the player objects file and set it equal to data
with open('PGA_Player_Objects.json') as json_file:
data = json.load(json_file)
points = []
players = []
for a in data:
for b in a['Tournament']:
points.append(int(float(b['Points'])))
for x in data:
players.append(x['Player_Name'])
def Average(lst):
unrounded = sum(lst) / len(lst)
return round(unrounded,2)
result = Counter()
for d in data:
for b in d['Tournament']:
result[d['Player_Name']] += int(float(b['Points']))
How can I do that?
if your list is in l:
l = [{'Player_Name': 'Byeong-Hun An', 'Tournament': [{'Name': 'Arnold Palmer Invitational presented by Mastercard', 'Points': '32.80', 'Salary': '10300.00'}]},
{'Player_Name': 'Byeong-Hun An', 'Tournament': [{'Name': 'Different', 'Points': '18.80', 'Salary': '10400.00'}]},]
Try this:
from itertools import groupby
result = []
for k,g in groupby(sorted(l, key=lambda x:x['Player_Name']), lambda x:x['Player_Name']):
result.append({'Player_Name':k, 'Tournament':[i['Tournament'][0] for i in g]})
Then the result will be:
[{'Player_Name': 'Byeong-Hun An',
'Tournament': [
{'Name': 'Arnold Palmer Invitational presented by Mastercard',
'Points': '32.80',
'Salary': '10300.00'},
{'Name': 'Different',
'Points': '18.80',
'Salary': '10400.00'}]}]
This works as well, and it's a more general solution that works for arbitrary key names:
from collections import defaultdict
d = defaultdict(list)
for dic in lst:
for k, v in dic.items():
if isinstance(v, list):
d[k].extend(v)
else:
d[k] = v
answer = [dict(d)]
Here's my take on a solution.
Create a new list of dictionaries
Iterate through the original list of dictionaries.
Store one copy of the beginning data for each player that is the same into the new list of dictionaries
Append additional Tournament data for each player into that one dictionary into a unified Tournament list.
Untested code below as an example, but should work with some tweaks.
listofDicts = [{'Player_Name': 'Byeong-Hun An', 'Tournament': [{'Name': 'Arnold Palmer Invitational presented by Mastercard', 'Points': '32.80', 'Salary': '10300.00'}]},{'Player_Name': 'Byeong-Hun An', 'Tournament': [{'Name': 'Different', 'Points': '18.80', 'Salary': '10400.00'}]}]
newListOfDicts = []
playerName = " "
playerNo = -1
for dicts in listofDicts:
if playerName == dicts['Player_Name']:
newListOfDicts[playerNo]['Tournament'].append(dicts['Tournament'][0])
else:
newListOfDicts.append(dicts)
playerName = dicts['Player_Name']
playerNo += 1
Description of the problem
The problem is a classical Bill of Materials (BoM) problem;
Suppose we have the class BomEntry(object) defined as:
class BomEntry:
def __init__(self, part, quantity=0, unit="", children=[]):
self.part = part
self.quantity = quantity
self.unit = unit
self.children = children
part is a django model, and quantity and unit are two of its members.
The Django model has a method make_bom(self) which returns an instance of BomEntry(a class which doesn't use django) . Asm is the django model keeping track of BoM data in the database
def make_bom(self, depth=1):
if not self.is_asm:
return BomEntry(self, 1, "", [])
else:
children = list(Asm.objects.filter(parent=self))
children_bom = [BomEntry(obj.child, obj.quantity, obj.unit, []) for obj in children]
bom = BomEntry(self, 1, "", children=children_bom)
return bom
I'm currently including a parameter to decide the depth of the BoM, but I can't wrap my head around how I would use it.
I want to be able to traverse the nested objects, ending up with an output similar to this:
{
'part': <PartAsm: 100-1822-R1-A>,
'quantity': 1,
'unit': '',
'children':
[
{
'part': <PartAsm: 100-1823-R1-A>,
'quantity': 1,
'unit': '',
'children':
[]
},
{
'part':
<PartAsm: 100-1824-R1-A>,
'quantity': 1,
'unit': '',
'children':
[
{
'part': <PartAsm: 100-1825-R1-A>,
'quantity': Decimal('1.00'),
'unit': 'g',
'children':
[]
},
{
'part': <PartAsm: 100-1826-R1-A>,
'quantity': Decimal('1.00'),
'unit': 'g',
'children':
[]
}
]
}
]
}
The output above was acquired using the console, I would appreciate any advice on looping this or making it recursive. I hope I provided sufficient and clear information
When depth is more than 1, make_bom() should recurse, decrementing depth in the call.
def make_bom(self, depth=1):
if not self.is_asm:
return BomEntry(self, 1, "", [])
else:
if depth > 1:
children = list(Asm.objects.filter(parent=self))
children_bom = [make_bom(BomEntry(obj.child, obj.quantity, obj.unit, []), depth-1) for obj in children]
else:
children_bom = []
bom = BomEntry(self, 1, "", children=children_bom)
return bom
I finally got it working using #Barmar 's valuable input. The make_bom function now looks like:
def make_bom(self, quantity=1, unit="def_unit", depth=1):
if not self.is_asm:
return BomEntry(self, quantity, unit, [])
else:
if depth <= 1:
children = list(Asm.objects.filter(parent=self))
children_bom = [BomEntry(obj.child, quantity*obj.quantity, obj.unit, []) for obj in children]
bom = BomEntry(self, quantity, unit, children=children_bom)
else:
bom = BomEntry(self, quantity, "def_unit",
children=[a.child.make_bom(quantity*a.quantity, a.unit, depth - 1) for a in
list(Asm.objects.filter(parent=self))])
return bom
I added in the quantity and unit params for completeness.
Thanks a million #Barmar
I have a json file like this (simplified):
{'pageSize': 1,
'vXPolicies':
[
{'columnType': 'Inclusion',
'id': 123,
'permMapList': [
{'groupList': ['kor1'], 'permList': ['Select1'], 'userList': []},
{'groupList': ['kor2'], 'permList': ['Select2'], 'userList': []}],
'policyName': 'DB_policy',
'version': '2'}]}
I want to add another list under "permMapList":
{'groupList': ['kor3'], 'permList': ['Select3'], 'userList': []}
You can use append:
your_dict['vXPolicies']['permMapList'].append(
{'groupList': ['kor3'], 'permList': ['Select3'], 'userList': []})
My collections has the following documents
{
cust_id: "0044234",
Address: "1234 Dunn Hill",
city: "Pittsburg",
comments : "4"
},
{
cust_id: "0097314",
Address: "5678 Dunn Hill",
city: "San Diego",
comments : "99"
},
{
cust_id: "012345",
Address: "2929 Dunn Hill",
city: "Pittsburg",
comments : "41"
}
I want to write a block of code that extracts and stores all cust_id's from the same city. I am able to get the answer by running the below query on MongoDB :
db.custData.find({"city" : 'Pittsburg'},{business_id:1}).
However, I am unable to do the same using Python. Below is what I have tried :
ctgrp=[{"$group":{"_id":"$city","number of cust":{"$sum":1}}}]
myDict={}
for line in collection.aggregate(ctgrp) : #for grouping all the cities in the dataset
myDict[line['_id']]=line['number of cust']
for key in myDict:
k=db.collection.find({"city" : 'key'},{'cust_id:1'})
print k
client.close()
Also, I am unable to figure out how can I store this. The only thing that is coming to my mind is a dictionary with a 'list of values' corresponding to a particular 'key'. However, I could not come up with an implementation about the same.I was looking for an output like this
For Pitssburg, the values would be 0044234 and 012345.
You can use the .distinct method which is the best way to do this.
import pymongo
client = pymongo.MongoClient()
db = client.test
collection = db.collection
then:
collection.distinct('cust_id', {'city': 'Pittsburg'})
Yields:
['0044234', '012345']
or do this client side which is not efficient:
>>> cust_ids = set()
>>> for element in collection.find({'city': 'Pittsburg'}):
... cust_ids.add(element['cust_id'])
...
>>> cust_ids
{'0044234', '012345'}
Now if you want all "cust_id" for a given city here it is
>>> list(collection.aggregate([{'$match': {'city': 'Pittsburg'} }, {'$group': {'_id': None, 'cust_ids': {'$push': '$cust_id'}}}]))[0]['cust_ids']
['0044234', '012345']
Now if what you want is group your document by city then here and find distinct "cust_id" then here is it:
>>> from pprint import pprint
>>> pipeline = [{'$group': {'_id': '$city', 'cust_ids': {'$addToSet': '$cust_id'}, 'count': {'$sum': 1}}}]
>>> pprint(list(collection.aggregate(pipeline)))
[{'_id': 'San Diego', 'count': 1, 'cust_ids': ['0097314']},
{'_id': 'Pittsburg', 'count': 2, 'cust_ids': ['012345', '0044234']}]
I am parsing JSON that stores various code snippets and I am first building a dictionary of languages used by these snippets:
snippets = {'python': {}, 'text': {}, 'php': {}, 'js': {}}
Then when looping through the JSON I'm wanting add the information about the snippet into its own dictionary to the dictionary listed above. For example, if I had a JS snippet - the end result would be:
snippets = {'js':
{"title":"Script 1","code":"code here", "id":"123456"}
{"title":"Script 2","code":"code here", "id":"123457"}
}
Not to muddy the waters - but in PHP working on a multi-dimensional array I would just do the following (I am lookng for something similiar):
snippets['js'][] = array here
I know I saw one or two people talking about how to create a multidimensional dictionary - but can't seem to track down adding a dictionary to a dictionary within python. Thanks for the help.
This is called autovivification:
You can do it with defaultdict
def tree():
return collections.defaultdict(tree)
d = tree()
d['js']['title'] = 'Script1'
If the idea is to have lists, you can do:
d = collections.defaultdict(list)
d['js'].append({'foo': 'bar'})
d['js'].append({'other': 'thing'})
The idea for defaultdict it to create automatically the element when the key is accessed. BTW, for this simple case, you can simply do:
d = {}
d['js'] = [{'foo': 'bar'}, {'other': 'thing'}]
From
snippets = {'js':
{"title":"Script 1","code":"code here", "id":"123456"}
{"title":"Script 2","code":"code here", "id":"123457"}
}
It looks to me like you want to have a list of dictionaries. Here is some python code that should hopefully result in what you want
snippets = {'python': [], 'text': [], 'php': [], 'js': []}
snippets['js'].append({"title":"Script 1","code":"code here", "id":"123456"})
snippets['js'].append({"title":"Script 1","code":"code here", "id":"123457"})
print(snippets['js']) #[{'code': 'code here', 'id': '123456', 'title': 'Script 1'}, {'code': 'code here', 'id': '123457', 'title': 'Script 1'}]
Does that make it clear?