Posts: 12,027
Threads: 485
Joined: Sep 2016
Wouldn't it be nice to be able to have two (or more) independent keys for a dictionary node?
I have a hack that does this, but was wondering if anyone has a better solution.
The Hack:
company = {
'xyz corp': {
'company_id': '12345',
'CompanyDetail': {
'Addr1': '45 Indianola Ave.',
'City': 'Columbus',
'State': 'Ohio'
}
},
'12345': {
'xref': 'xyz corp'
}
}
def find_company(key):
if 'xref' in company[key]:
company_info = company[company[key]['xref']]
else:
company_info = company[key]
print(company_info)
find_company('12345')
find_company('xyz corp') Output: {'company_id': '12345', 'CompanyDetail': {'Addr1': '45 Indianola Ave.', 'City': 'Columbus', 'State': 'Ohio'}}
{'company_id': '12345', 'CompanyDetail': {'Addr1': '45 Indianola Ave.', 'City': 'Columbus', 'State': 'Ohio'}}
Posts: 4,220
Threads: 97
Joined: Sep 2016
Dec-20-2018, 06:14 PM
(This post was last modified: Dec-20-2018, 06:16 PM by ichabod801.)
I usually do that through an alias dictionary:
company = {
'xyz corp': {
'company_id': '12345',
'CompanyDetail': {
'Addr1': '45 Indianola Ave.',
'City': 'Columbus',
'State': 'Ohio'
}
}
}
company_aliases = {'12345': 'xyz corp', 'xyz': 'xyz corp'}
company[company_aliases.get('12345', '12345')]
company[company_aliases.get('xyz corp', 'xyz corp')] You can also put the standard names keyed to themselves in the aliases dictionary, and then you don't need to use get (you just need to maintain that information as new companies are loaded).
Posts: 4,785
Threads: 76
Joined: Jan 2018
Dec-20-2018, 06:44 PM
(This post was last modified: Dec-20-2018, 06:44 PM by Gribouillis.)
Why not
company = {
'xyz corp': {
'company_id': '12345',
'CompanyDetail': {
'Addr1': '45 Indianola Ave.',
'City': 'Columbus',
'State': 'Ohio'
}
}
}
company['12345'] = company['xyz corp'] Nothing prevents different keys to point to the same value.
Posts: 12,027
Threads: 485
Joined: Sep 2016
Dec-20-2018, 07:02 PM
(This post was last modified: Dec-20-2018, 07:02 PM by Larz60+.)
Quote:ichabod801 writes:
I usually do that through an alias dictionary:
company = {
'xyz corp': {
'company_id': '12345',
'CompanyDetail': {
'Addr1': '45 Indianola Ave.',
'City': 'Columbus',
'State': 'Ohio'
}
}
}
company_aliases = {'12345': 'xyz corp', 'xyz': 'xyz corp'}
company[company_aliases.get('12345', '12345')]
company[company_aliases.get('xyz corp', 'xyz corp')]
You can also put the standard names keyed to themselves in the aliases dictionary, and then you don't need to use get (you just need to maintain that information as new companies are loaded).
The problem with this is that there's two separate dictionaries needed, I'd like it to be self contained
Quote:Gribouillis writes:
Why not
company = {
'xyz corp': {
'company_id': '12345',
'CompanyDetail': {
'Addr1': '45 Indianola Ave.',
'City': 'Columbus',
'State': 'Ohio'
}
}
}
company['12345'] = company['xyz corp'] Nothing prevents different keys to point to the same value.
The problem here is that this creates a copy of the data, which is not what I want. I should probably use sqlite3, but would like to avoid the overhead and performance cost.
Posts: 4,785
Threads: 76
Joined: Jan 2018
Dec-20-2018, 07:10 PM
(This post was last modified: Dec-20-2018, 07:11 PM by Gribouillis.)
Larz60+ Wrote:The problem here is that this creates a copy of the data It does not create a copy of the data. It works like hard links in a linux system. The problem is that if you change one of the links, it doesn't update the others. For this you need another level of indirection, that is to say ichabod801's solution, or your solution, which works like symbolic links in a linux system.
Posts: 12,027
Threads: 485
Joined: Sep 2016
Dec-20-2018, 07:16 PM
(This post was last modified: Dec-20-2018, 07:17 PM by Larz60+.)
Quote:It does not create a copy of the data
I printed the dictionary and looked like a copy, so I was thrown off.
so it's really not there, works like symbolic link, OK ...
what happens if I want to dump as JSON?
Posts: 4,220
Threads: 97
Joined: Sep 2016
(Dec-20-2018, 07:02 PM)Larz60+ Wrote: The problem with this is that there's two separate dictionaries needed, I'd like it to be self contained
Well, if you put them both in another dict ( company_data = {'values': company, 'aliases': company_aliases} ), your find_company function is simpler:
def find_company(key):
return company_data['values'][company_data['aliases'].get(key, key)]
Posts: 4,220
Threads: 97
Joined: Sep 2016
Come to think of it, you could create a sub-class of dictionary (UserDictionary?) that handles all of this on the sly.
Posts: 12,027
Threads: 485
Joined: Sep 2016
Quote:Griboullis asks Why not
I guess because I dodn't know I could!
Learned something new.
Will try saving as JSON
Posts: 12,027
Threads: 485
Joined: Sep 2016
Dec-20-2018, 07:37 PM
(This post was last modified: Dec-20-2018, 07:37 PM by Larz60+.)
here is what the JSON file looks like (Griboullis solution)
Output: {"xyz corp": {"company_id": "12345", "CompanyDetail": {"Addr1": "45 Indianola Ave.", "City": "Columbus", "State": "Ohio"}}, "12345": {"company_id": "12345", "CompanyDetail": {"Addr1": "45 Indianola Ave.", "City": "Columbus", "State": "Ohio"}}}
code:
import BusinessPaths
import json
bpath = BusinessPaths.BusinessPaths()
company = {
'xyz corp': {
'company_id': '12345',
'CompanyDetail': {
'Addr1': '45 Indianola Ave.',
'City': 'Columbus',
'State': 'Ohio'
}
}
}
company['12345'] = company['xyz corp']
json_file = bpath.tmppath / 'comp.json'
with json_file.open('w') as fp:
json.dump(company, fp)
print(company) Output: {'xyz corp': {'company_id': '12345', 'CompanyDetail': {'Addr1': '45 Indianola Ave.', 'City': 'Columbus', 'State': 'Ohio'}}, '12345': {'company_id': '12345', 'CompanyDetail': {'Addr1': '45Indianola Ave.', 'City': 'Columbus', 'State': 'Ohio'}}}
sure looks like a copy of data, maybe not in the dictionary, but when saved?
|