Python Forum
Independent Secondary index for dictionary
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Independent Secondary index for dictionary
#1
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'}}
Reply
#2
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).
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
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.
Reply
#4
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.
Reply
#5
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.
Reply
#6
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?
Reply
#7
(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)]
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#8
Come to think of it, you could create a sub-class of dictionary (UserDictionary?) that handles all of this on the sly.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#9
Quote:Griboullis asks Why not
I guess because I dodn't know I could!
Learned something new.
Will try saving as JSON
Reply
#10
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?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Multiple user defined plots with secondary axes using for loop maltp 1 1,459 Apr-30-2022, 10:19 AM
Last Post: maltp
  Making a plot with secondary y-axis bigger snkm 0 1,134 Feb-10-2022, 09:40 AM
Last Post: snkm
  Loop independent of excecution time of a script Forelli 8 3,822 Feb-02-2020, 10:49 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020