crashwap
crashwap

Reputation: 3062

Python lookup table that returns multiple values

I wish to have a lookup table return multiple values.

For example, if user's name is "joe", I would like to return an object such as:

{'name': 'Joseph', 'gender': 'm', 'xro': 'xy'}

At the moment, I have a function that accepts an input, matches it to one of the predefined forms, and returns the definitive form:

def names_lookup(txt):
    name_forms = {
        'Joseph': ['joe', 'joseph', 'guiseppe', 'joey'],
        'Samuel': ['sam', 'samuel', 'shmuel', 'kamuel']
    }
    for canon in name_forms:
        for variant in name_forms[canon]:
            if txt.lower() == variant.lower():
                return canon

cannonical_name = names_lookup('joey'); #returns "Joseph"

At the moment I have multiple lookup tables to return the other values I need to construct my object - but is there a way to have a single lookup table that returns an object?

So, the desired output would be:

cannonical_name = new_names_lookup('joey')
#returns: {'name': 'Joseph', 'gender': 'm', 'xro': 'xy'}

Upvotes: 0

Views: 1883

Answers (3)

Heavenly Raven
Heavenly Raven

Reputation: 83

Depends on the problem. What exactly do you want?

I can only come up with something like this:

    def lookup(txt):
        name_forms = {
       'Joseph': ['joe', 'joseph', 'guiseppe', 'joey'], 
       'Samuel': ['sam', 'samuel', 'shmuel', 'kamuel'], 
       'Maria': ['mary', 'marie', 'miriam', 'mariana']}
        for i, canon in enumerate(name_forms):
            for variant in name_forms[canon]:
                if txt.lower() == variant.lower():
                    if i <= 1:
                        gender = 'm'
                        xro = 'xy'
                    else:
                        gender = 'f'
                        xro = 'xx'
                    return {'name': canon, 'gender': gender, 'xro': xro}

    lookup('joey')

I didn't change your look-up method, but it's definitely not effective as others already mentioned.

Upvotes: 2

Prune
Prune

Reputation: 77837

You have two straightforward choices. One is the standard look-up list, as in Evan's comment:

{'guiseppe': 'Joseph', 'joe': 'Joseph', 'joey': 'Joseph', 'joseph': 'Joseph',
 'Samuel': 'Samuel', 'sam': 'Samuel', 'samuel': 'Samuel', 'shmuel': 'Samuel'}

Now, adapt this to return the full object, rather than the name. Since you didn't specify an object, I'll assume a Person class:

joseph = Person(name = "Joseph", gender = "m", xro = "xy")
samuel = Person(name = "Samuel", gender = "m", xro = "xy")

Now, just insert the objects into your look-up table:

{'guiseppe': joseph, 'joe': joseph, 'joey': joseph, 'joseph': 'Joseph',
 'Samuel': samuel, 'sam': samuel, 'samuel': samuel, 'shmuel': 'Samuel'}

The other look-up method is to remove the extra loop from your existing code; use the in operator:

for canon in name_forms:
    for variant in name_forms[canon]:
        if txt.lower() in variant:
            return canon

You will still need a string-to-object table, but now it's shorter:

{"Joseph": jospeh, "Samuel": samuel}

Upvotes: 3

Born Tbe Wasted
Born Tbe Wasted

Reputation: 610

I don't know how many values you wish to store, but looping through everything looks like a hassle.

Have you tried storing your data in another way ? (As other suggest , didn't see the other answers)

Maybe :

name_forms = {
'joe':'Joseph',
'joseph':'Joseph',
'guiseppe':'Joseph',
'joey':'Joseph',
'sam':'Samuel',
'samuel':'Samuel',
'shmuel':'Samuel',
'kamuel':'Samuel'
}
other_format={
   'Joseph': ['joe', 'joseph', 'guiseppe', 'joey'],
    'Samuel': ['sam', 'samuel', 'shmuel', 'kamuel']
}

def names_lookup(txt):
    if txt in name_forms:
        return name_forms[txt]
     else:
        return None

And if you do not wish to store it this way , you can create it via

 data_base = {x:k for k,v in other_format.items()  for x in v}

Besides, if you do not wish to continue manually typing the variants of those words, you can take a look at cosine similarity.

Upvotes: 1

Related Questions