Python Forum
Independent Secondary index for dictionary - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Independent Secondary index for dictionary (/thread-14860.html)

Pages: 1 2


Independent Secondary index for dictionary - Larz60+ - Dec-20-2018

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



RE: Independent Secondary index for dictionary - ichabod801 - Dec-20-2018

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


RE: Independent Secondary index for dictionary - Gribouillis - Dec-20-2018

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.


RE: Independent Secondary index for dictionary - Larz60+ - Dec-20-2018

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.


RE: Independent Secondary index for dictionary - Gribouillis - Dec-20-2018

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.


RE: Independent Secondary index for dictionary - Larz60+ - Dec-20-2018

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?


RE: Independent Secondary index for dictionary - ichabod801 - Dec-20-2018

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



RE: Independent Secondary index for dictionary - ichabod801 - Dec-20-2018

Come to think of it, you could create a sub-class of dictionary (UserDictionary?) that handles all of this on the sly.


RE: Independent Secondary index for dictionary - Larz60+ - Dec-20-2018

Quote:Griboullis asks Why not
I guess because I dodn't know I could!
Learned something new.
Will try saving as JSON


RE: Independent Secondary index for dictionary - Larz60+ - Dec-20-2018

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?