0

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?

1
  • And how will this "choice" function work ? if you always choose the first word - you'll get the exact same word while on the other hand - not all words have a synonym. Only option I can think of is using random % array-size which won't be consistent (if that matters). Commented Jun 19, 2014 at 1:48

3 Answers 3

3

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
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! this is exactly what I was looking for. I was going to extend string.Formatter but this is much simpler.
1

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.

2 Comments

Thanks Tok, but this introduces the same issue as below. I am looping over a whole bunch of different string with different keys to the thesaurus. I won't know the key 'cold' ahead of time and need to be able to dynamically use that key to retrieve the list and then select one of the words at random.
You can make a function which is defines that a certain word is present in a thesaurus, and then use this word as a key of dictionary.
0

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.

2 Comments

I need this to be dynamic - I don't know the key ahead of time, so I wouldn't know the argument to pass to getSynonym.
In that case just pass the variable key into the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.