0

I have a list of words named words and I would like to generate a list of 100 three-words elements named pwds. I want these 3 words to be randomly picked from the words list for each element of the pwds list, and I'd like to use list comprehension to do this.

This solution works :

pwds = [random.choice(words)+' '+random.choice(words)+' '+random.choice(words) for i in range(0,100)]

It generates a list that looks like : ['correct horse battery', 'staple peach peach', ...]

But I was looking for a way that prevents repetiting 3 times random.choice(words), so I tried this :

pwds = [(3*(random.choice(words)+' ')).strip() for i in range(0,100)]

But unfortunately, this solution makes each element having the same word three times (for example : ['horse horse horse', 'staple staple staple', ...]), which is expected to happend.

Do you know a way to pick 3 random words without repetition (EDIT : by "repetition", I mean the code repetition, not the random words repetition) ?

EDIT : My question is different than the one it has been marked as duplicate of because I'm looking for using list comprehension here. I know how I could generate different numbers, I'm just looking for specific way to do it.

2
  • 1
    random.sample? Commented Aug 29, 2014 at 9:20
  • @jonrsharpe: This function is great, I came up with this solution : pwds = [' '.join(random.sample(words,3)) for i in range(0,100)]. But this function prevents the possibility that the same word occurs 2 or 3 times in the same element. Commented Aug 29, 2014 at 9:30

2 Answers 2

2

If you want the words to be able to repeat within each triplet, I think what you want is something like:

pwds = [" ".join(random.choice(words) for _ in range(3)) for _ in range(100)]

Note the use of _ to indicate that we don't actually use the numbers generated by either range, and the fact that range(0, n) is the same as range(n).

A somewhat shorter example:

>>> import random
>>> words = ['correct', 'horse', 'battery', 'staple']
>>> [" ".join(random.choice(words) for _ in range(3)) for _ in range(5)]
['horse horse correct', 
 'correct staple staple', 
 'correct horse horse', 
 'battery staple battery', 
 'horse battery battery']
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, it's exactly what I was looking for! Thanks for your coding advice too.
1

You can use the join function and a list comprehension to not repeat random.choice

pwds = [' '.join([random.choice(words) for _ in range(3)]) for _ in range(100)]

4 Comments

Although it is the same answer than jonrsharpe, yours helps to understand that we are using a nested list comprehension, which I didn't understand at first.
Absolutly, jonrsharpe was just faster than me.
Actually, this is slightly better than my approach, as passing a list (rather than the bare generator expression) to str.join is more efficient - see stackoverflow.com/a/9061024/3001761
@SeevenByakko no problem. It won't make much difference with three items, but it's worth knowing about.

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.