How to choose randomly in Python - python-3.x

I have to write a code in python that chooses a word from 7 lists (total of 7 words) and then runs a requested number of lines to form a "poem". Each line of the "poem" is meant to be a different combination of the 7 lists. Any ideas of how to get the program to run different combinations? Mine just runs the same line the number of times I asked:
people=['Amir', 'Itai', 'Sheli','Gil','Jasmin','Tal','Nadav']
verbs = ['talks', 'smiles', 'sings', 'listens', 'eats', 'waves', 'plays', 'swims']
Adverbs =['slowly', 'quickly', 'solemnly', 'nicely', 'beautifully']
Prepositions=['to a', 'with a' ,'towards a', 'at a' ,'out of a']
Adjectives =['white', 'blue', 'green', 'small', 'large', 'yellow', 'pretty', 'sad']
Animated=['fish', 'parrot', 'flower', 'tree', 'snake']
Inanimated=['chair', 'lamp', 'car', 'ship', 'boat']
x=eval(input("How many lines are in the poem?"))
y=(random.choice(people), random.choice (verbs) ,random.choice(Adverbs) ,random.choice(Prepositions) ,random.choice(Adjectives) ,random.choice(Animated+Inanimated))
for i in range (x):
if (x< 10):
print (y)

You have the right idea, but you just need to re-evaluate the random choice each time:
people=['Amir', 'Itai', 'Sheli','Gil','Jasmin','Tal','Nadav']
verbs = ['talks', 'smiles', 'sings', 'listens', 'eats', 'waves', 'plays', 'swims']
Adverbs =['slowly', 'quickly', 'solemnly', 'nicely', 'beautifully']
Prepositions=['to a', 'with a' ,'towards a', 'at a' ,'out of a']
Adjectives =['white', 'blue', 'green', 'small', 'large', 'yellow', 'pretty', 'sad']
Animated=['fish', 'parrot', 'flower', 'tree', 'snake']
Inanimated=['chair', 'lamp', 'car', 'ship', 'boat']
x=eval(input("How many lines are in the poem?"))
for i in range (x):
y=(random.choice(people), random.choice (verbs) ,random.choice(Adverbs) ,random.choice(Prepositions) ,random.choice(Adjectives) ,random.choice(Animated+Inanimated))
if (i < 10):
print (y)

I think this can help you:
import random
people=['Amir', 'Itai', 'Sheli','Gil','Jasmin','Tal','Nadav']
verbs = ['talks', 'smiles', 'sings', 'listens', 'eats', 'waves', 'plays', 'swims']
Adverbs =['slowly', 'quickly', 'solemnly', 'nicely', 'beautifully']
Prepositions=['to a', 'with a' ,'towards a', 'at a' ,'out of a']
Adjectives =['white', 'blue', 'green', 'small', 'large', 'yellow', 'pretty', 'sad']
Animated=['fish', 'parrot', 'flower', 'tree', 'snake']
Inanimated=['chair', 'lamp', 'car', 'ship', 'boat']
while True:
x=eval(input("How many lines are in the poem?"))
if x == 0:
break
for i in range (x):
if (x< 10):
y = (random.choice(people), random.choice(verbs), random.choice(Adverbs), random.choice(Prepositions),random.choice(Adjectives), random.choice(Animated + Inanimated))
print (y)

Related

How to convert loop to shortest list comprehension form?

I'm trying to get the shortest code to obtaina list of unique parameters (in order of appearence). These parameters are to the left
of each parameter = something. I was able to build the below loop that works and stores in h the parameters
data = [
'B = 3',
'T = 0',
'N = 5',
'V = 2',
'N = 1',
'V = 4',
'B = 7',
'T = 2',
]
h = []
for d in data:
el = d.split("=", 1)[0].strip()
if el not in h:
h.append(el)
>>> h
['B', 'T', 'N', 'V']
Then, I'd like to convert this in list comprehension and this works but I think there would be a way to write it even shorter without repeat the
part d.split("=", 1)[0].strip() twice.
h = []
[h.append(d.split("=", 1)[0].strip()) for d in data if d.split("=", 1)[0].strip() not in h ]
I've tried this but doesn't seem to be the correct syntax.
h = []
[el = d.split("=", 1)[0].strip() h.append(el) for d in data if el not in h ]
While preserving order (and assuming you really only want the first character):
list(dict.fromkeys(s[0] for s in data))
Or to get the first set of characters before a space:
list(dict.fromkeys([s.split()[0] for s in data]))
You could also get fancy with this using map and operator.itemgetter
from operator import itemgetter
list(dict.fromkeys(map(itemgetter(0), map(split, data))))
Try:
h = list(set(s.split()[0].strip() for s in data))
print(h)
Prints:
['N', 'V', 'B', 'T']

Create a list of maps from multiple lists

Given three lists:
l1 = ['Alice', 'Bob', 'Jane']
l2 = ['30', '40', '50']
l3 = ['NY', 'Berlin', 'Stockholm']
how do I create something like this:
[['name': 'Alice', 'age': '30', 'city': 'NY'],
['name': 'Bob', 'age': '40', 'city': 'Berlin'],
['name': 'Jane', 'age': '50', 'city': 'Stockholm']]
I've tried [l1,l2,l3].transpose() but it returns list of lists and I can't figure out how to add proper keys to collectEntries()
Thanks
Edit:
Not-so-elegant solution I came up with is this:
assert l1.length == l2.length
assert l2.length == l3.length
def mapping = []
l1.eachWithIndex {name, index ->
def obj = [:]
obj.name = name
obj.age = l2[index]
obj.city = l3[index]
mapping += obj
obj = []
};
But there must be a better way, right?
An attempt at solving this more elegantly.
The following code:
def l1 = ['Alice', 'Bob', 'Jane']
def l2 = ['30', '40', '50']
def l3 = ['NY', 'Berlin', 'Stockholm']
def result = [l1, l2, l3].transpose().collect { a, b, c ->
[name: a, age: b, city: c]
}
println result
when run, prints out:
~> groovy solution.groovy
[[name:Alice, age:30, city:NY],
[name:Bob, age:40, city:Berlin],
[name:Jane, age:50, city:Stockholm]]
~>
(formatting added for readability).
The trick here is the transpose method which the question already mentions - [l1, l2, l3].transpose() returns:
[[Alice, 30, NY], [Bob, 40, Berlin], [Jane, 50, Stockholm]]
and the collect { a, b, c -> expression uses groovy destructuring to assign [Alice, 30, NY] to a, b, c etc. This is essentially the same mechanics that make it possible to write:
def (a, b, c) = [1, 2, 3]
for multiple assignments.
collectEntries returns a map and since you want a list on the outermost level it's not really the right tool here.

join strings within a list of lists by 4

Background
I have a list of lists as seen below
l = [['NAME',':', 'Mickey', 'Mouse', 'was', 'here', 'and', 'Micky', 'mouse', 'went', 'out'],
['Donal', 'duck', 'was','Date', 'of', 'Service', 'for', 'Donald', 'D', 'Duck', 'was', 'yesterday'],
['I', 'like','Pluto', 'the', 'carton','Dog', 'bc','he', 'is','fun']]
Goal
Join l by every 4 elements (when possible)
Problem
But sometimes 4 elements won't cleanly join as 4 as seen in my desired output
Desired Output
desired_l = [['NAME : Mickey Mouse', 'was here and Micky', 'mouse went out'],
['Donal duck was Date', 'of Service for Donald', 'D Duck was yesterday'],
['I like Pluto the', 'carton Dog bc he', 'is fun']]
Question
How do I achive desired_l?
itertools has some nifty functions, one of which can do this to do just this.
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
[[' '.join(filter(None, x)) for x in list(grouper(sentence, 4, fillvalue=''))] for sentence in l]
Result:
[['NAME : Mickey Mouse', 'was here and Micky', 'mouse went out'],
['Donal duck was Date', 'of Service for Donald', 'D Duck was yesterday'],
['I like Pluto the', 'carton Dog bc he', 'is fun']]

How do I join portions of a list in Python

Trying to join only portions of a large list that has numbers in it. For example:
h = ['9 This is the way this is the way 10 to program a string 11 to program a string']
##I've tried...
h[0].split()
z = []
h = ['9', 'This', 'is', 'the', 'way', 'this', 'is', 'the', 'way', '10', 'to', 'program', 'a', 'string', '11', 'to', 'program', 'a', 'string']
for i in h:
while i != '10':
z.append(i)
But the program runs an infinite loop. I've also tried if statements, if i != '10' then z.append(i). Basically, I have large portions of scripture that is in a list as a single string and I'd like to quickly extract the verses and put them in their own separate list. Thank you
Edit: I've tried...
h= ['9 nfnf dhhd snsn nana na 10 hfhf gkg utu 11 oeoe ldd sss', 'kgk hfh']
y = h[0].split()
print (y)
z = []
for i in y:
if i != "10":
z.append(i)
break
print (z)
Output is the split list and 'z' prints '9' only. I've also changed the break to the correct indentation for the 'for' loop
First of all, use the result you get from h[0].split(). You can do this by using h = h[0].split()
Now, lets get to the loop. It's going into an infinite loop because the for loop is picking the first i which is "9" and then while i != "10", it keeps appending i to z. i will never equal "10". Thus, the infinite loop. I think what you want here is:
for i in h:
if i != "10":
z.append(i)
else:
break
This will append every value of h into z until i is equal to "10". Let me know if you need more help and I'll be happy to edit!
Try this for extracting all numbers in z:
h = ['9 This is the way this is the way 10 to program a string 11 to program a string']
##I've tried...
h = h[0].split()
z = []
for i in h:
try:
z.append(eval(i))
except:
pass
print z
output:
[9, 10, 11]
[Finished in 0.0s]

Why may this construction be not working?

I receive, that first iteration 1 is not a number.
numbers = ['1', 'apple', '2', '3', '4', '5']
print ('Your numbers are...')
for f in numbers:
if f.isalpha():
print ('This is not a number!') # (It actually isn't.)
break
print (f)
else:
print ('Here are your numbers!')
You're seeing this...
Your numbers are...
Then you hit the first iteration, f = '1' and print (f):
1
Then you get to the second iteration, f = 'apple' and print ('This is not a number!')...
This is not a number!
This is to be expected.
Your output would be clearer with this program:
#!/usr/bin/env python3
numbers = ['1', 'apple', '2', '3', '4', '5']
print ('Your numbers are...')
for f in numbers:
if f.isalpha():
print('{} is not a number!'.format(f))
break
else:
print('Here are your numbers: {}'.format(numbers))

Resources