Comart
Comart

Reputation: 64

Python string format using dict of arrays

I have a thesaurus (dictionary) of values:

words = dict( 
  'hot' = ['hot', 'scalding', 'warm'],
  'cold' = ['cold', 'frigid', 'freezing'],
   ...)

And I would like to use this thesaurus to loop over a list of strings formatting the tags with random entries from the thesaurus. I won't know what the key words are ahead of time.

phrases = ['the water is {word.cold}', 'the sun is {word.hot}', ...]
formatted = [phrase.format(word=words, somerandomizingfunction) for phrase in phrases]

But this (as expected) is inserting the entire array into the string. Is there a way to pass a choice function to format or do I need to write my own custom format functionality including the word/key matching?

Upvotes: 0

Views: 724

Answers (3)

khampson
khampson

Reputation: 15356

It's not custom format functionality that's needed, per se. format simply takes values (and, optionally an assortment of formatting specifications).

I would recommend you define a function which takes the source word and returns the synonym based on the heuristic you would like (a random element of the list, perhaps), and then call that function inside of the call to format instead.

i.e. something like

'the water is {0}'.format(getSynonym('cold'))

Edit in response to comment from OP:

If you have dynamic keys, you could pass the variable representing the key directly into your function.

Upvotes: 0

nOOb cODEr
nOOb cODEr

Reputation: 236

I believe you can achieve what you want by subclassing the builtin dict class. See a debuggable/steppable demo of the code below at http://dbgr.cc/k

import random

class WordDict(dict):
    def __getitem__(self, key):
        vals = dict.__getitem__(self, key)
        return random.choice(vals)

words = WordDict(
    cold = ["cold", "frigid", "freezing"],
    hot = ["scathing", "burning", "hot"]
)

for x in xrange(10):
    print('the water is {word[cold]}'.format(word=words))

overriding the __getitem__ method will let you make assumptions about what each value of each key/value pair will be (a list), at which point you can just return a random item from the list of values.

The output of the above code is below:

the water is freezing
the water is cold
the water is freezing
the water is frigid
the water is cold
the water is frigid
the water is cold
the water is freezing
the water is freezing
the water is freezing

UPDATE

Just to make sure my answer completely matches your question/request, I've tweaked the code above to include the phrases array. Demoable/debuggable/steppable at http://dbgr.cc/n

import random

class WordDict(dict):
    def __getitem__(self, key):
        vals = dict.__getitem__(self, key)
        return random.choice(vals)

words = WordDict(
    cold = ["cold", "frigid", "freezing"],
    hot = ["scathing", "burning", "hot"]
)

phrases = ['the water is {word[cold]}', 'the sun is {word[hot]}']

for x in xrange(10):
    for phrase in phrases:
        print phrase.format(word=words)

The output:

the water is frigid
the sun is scathing
the water is freezing
the sun is burning
the water is freezing
the sun is hot
the water is cold
the sun is scathing
the water is freezing
the sun is hot
the water is cold
the sun is scathing
the water is frigid
the sun is scathing
the water is frigid
the sun is hot
the water is frigid
the sun is scathing
the water is freezing
the sun is hot

Upvotes: 3

Tok Soegiharto
Tok Soegiharto

Reputation: 329

How about this approach:

import random

words = dict(hot=['hot', 'scalding', 'warm'],
             cold=['cold', 'frigid', 'freezing'])

Demo:

>>> 
>>> 'the water is {}'.format(random.choice(words['cold']))
'the water is frigid'
>>> 'the water is {}'.format(random.choice(words['cold']))
'the water is freezing'
>>> 'the water is {}'.format(random.choice(words['cold']))
'the water is frigid'
>>> 'the water is {}'.format(random.choice(words['cold']))
'the water is cold'
>>> 

Hopes can help you.

Upvotes: 1

Related Questions