I was supposed to built a program that would automatically print the lyrics of a song (twelve days of christmas) so that it re-prints the same message in each line, but extended by the new lyric pertaining to that line.
For instance:
verse1 = '''On the first day of Christmas
my true love sent to me:
A Partridge in a Pear Tree''''
verse2 = '''On the second day of Christmas
my true love sent to me:
2 Turtle Doves
and a Partridge in a Pear Tree'''
I get stuck with the loops and ' "TypeError: '<' not supported between instances of 'str' and 'int'" '. What I do know is that I will have to use the .join() statement. Thank you in advance.
Here is a naive implementation (reference for the content):
verses = ['a partridge in a pear tree', 'two turtle doves', 'three French hens',
'four calling birds', 'five gold rings', 'six geese a-laying',
'seven swans a-swimming', 'eight maids a-milking', 'nine ladies dancing',
'ten lords a-leaping', 'eleven pipers piping', 'twelve drummers drumming']
days = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth',
'seventh', 'eigth', 'ninth', 'tenth', 'eleventh', 'twelfth']
for i, day in enumerate(days):
print(f'On the {day} day of Christmas,\nmy true love sent to me:')
for verse in verses[i::-1]:
print(verse)
if i == 0:
verses[0] = 'and ' + verses[0]
print()
Output:
On the first day of Christmas,
my true love sent to me:
a partridge in a pear tree
On the second day of Christmas,
my true love sent to me:
two turtle doves
and a partridge in a pear tree
On the third day of Christmas,
my true love sent to me:
three French hens
two turtle doves
and a partridge in a pear tree
On the fourth day of Christmas,
my true love sent to me:
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the fifth day of Christmas,
my true love sent to me:
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the sixth day of Christmas,
my true love sent to me:
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the seventh day of Christmas,
my true love sent to me:
seven swans a-swimming
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the eigth day of Christmas,
my true love sent to me:
eight maids a-milking
seven swans a-swimming
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the ninth day of Christmas,
my true love sent to me:
nine ladies dancing
eight maids a-milking
seven swans a-swimming
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the tenth day of Christmas,
my true love sent to me:
ten lords a-leaping
nine ladies dancing
eight maids a-milking
seven swans a-swimming
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the eleventh day of Christmas,
my true love sent to me:
eleven pipers piping
ten lords a-leaping
nine ladies dancing
eight maids a-milking
seven swans a-swimming
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
On the twelfth day of Christmas,
my true love sent to me:
twelve drummers drumming
eleven pipers piping
ten lords a-leaping
nine ladies dancing
eight maids a-milking
seven swans a-swimming
six geese a-laying
five gold rings
four calling birds
three French hens
two turtle doves
and a partridge in a pear tree
Related
I am following this example semantic clustering:
!pip install sentence_transformers
from sentence_transformers import SentenceTransformer
from sklearn.cluster import KMeans
embedder = SentenceTransformer('all-MiniLM-L6-v2')
# Corpus with example sentences
corpus = ['A man is eating food.',
'A man is eating a piece of bread.',
'A man is eating pasta.',
'The girl is carrying a baby.',
'The baby is carried by the woman',
'A man is riding a horse.',
'A man is riding a white horse on an enclosed ground.',
'A monkey is playing drums.',
'Someone in a gorilla costume is playing a set of drums.',
'A cheetah is running behind its prey.',
'A cheetah chases prey on across a field.'
]
corpus_embeddings = embedder.encode(corpus)
# Perform kmean clustering
num_clusters = 5
clustering_model = KMeans(n_clusters=num_clusters)
clustering_model.fit(corpus_embeddings)
cluster_assignment = clustering_model.labels_
clustered_sentences = [[] for i in range(num_clusters)]
for sentence_id, cluster_id in enumerate(cluster_assignment):
clustered_sentences[cluster_id].append(corpus[sentence_id])
for i, cluster in enumerate(clustered_sentences):
print("Cluster", i+1)
print(cluster)
print(len(cluster))
print("")
Which results to the following lists:
Cluster 1
['The girl is carrying a baby.', 'The baby is carried by the woman']
2
Cluster 2
['A man is riding a horse.', 'A man is riding a white horse on an enclosed ground.']
2
Cluster 3
['A man is eating food.', 'A man is eating a piece of bread.', 'A man is eating pasta.']
3
Cluster 4
['A cheetah is running behind its prey.', 'A cheetah chases prey on across a field.']
2
Cluster 5
['A monkey is playing drums.', 'Someone in a gorilla costume is playing a set of drums.']
2
How to add these separate list to one?
Expected outcome:
list2[['The girl is carrying a baby.', 'The baby is carried by the woman'], .....['A monkey is playing drums.', 'Someone in a gorilla costume is playing a set of drums.']]
I tried the following:
list2=[]
for i in cluster:
list2.append(i)
list2
But I returns me only the last one:
['A monkey is playing drums.',
'Someone in a gorilla costume is playing a set of drums.']
Any ideas?
Following that example, you don't need to anything to get a list of lists; that's already been done for you.
Try printing clustered_sentences.
Basically, you need to get a "flat" list from a list of lists, you can achieve that with python list comprehension:
flat = [item for sub in clustered_sentences for item in sub]
I have a dataframe like following
dfx=pd.DataFrame({'Title':
['These cats are very cute',
'dogs and horse is a loyal animal',
'chicken layes eggs full of proteins',
'lion is the king of jungle']})
and another data frame of keyword like this
kwx=pd.DataFrame({'Tag':['cats','cute','dogs','horse','chicken', 'proteins', 'lion','jungle','eggs'],
'Area':['animal',np.NaN,'animal','animal','bird','food','animal','place','food']
})
What is want to do is to search Tag from kwx in Title of dfx. And if tag is present, merge the kwx row of that tag with title.
Here is what I have done.
Split the title and search each tag in title, and return the first two match results.
dfx['splittitle'] = dfx['Title'].str.lower().str.split()#strop title
dfx['matchedName'] = dfx['splittitle'].apply(lambda x: [item for item in x if item in kwx['Tag'].tolist()])
dfx[['term1','term2']] = dfx.matchedName.apply(pd.Series).iloc[:,0:2]#return only two matches
dfx.drop('splittitle',axis=1,inplace=True)
Output
Title matchedName term1 term2
These cats are very cute ['cats', 'cute'] cats cute
dogs and horse is a loyal animal ['dogs', 'horse'] dogs horse
chicken layes eggs full of proteins ['chicken', 'eggs', 'proteins'] chicken eggs
lion is the king of jungle ['lion', 'jungle'] lion jungle
The next step i performed is to merge the term1 and term2 column with kwx dataframe
merged_dfx = dfx.merge(kwx, how='inner',left_on=['term1'],right_on='Tag',suffixes=('_1','_2'))
merged_dfx = merged_dfx.merge(kwx, how='inner',left_on=['term2'],right_on='Tag',suffixes=('_1','_2'))
merged_dfx.drop(['Tag_1','Tag_2'],axis=1,inplace=True)
Output
Title matchedName term1 term2 Area_1 Area_2
These cats are very cute ['cats', 'cute'] cats cute animal
dogs and horse is a loyal animal ['dogs', 'horse'] dogs horse animal animal
chicken layes eggs full of proteins ['chicken', 'eggs', 'proteins'] chicken eggs bird food
lion is the king of jungle ['lion', 'jungle'] lion jungle animal place
The output i want. Instead of confining to only first two match, i want all results and want dataframe in following shape
Output
Title term Area
These cats are very cute ['cats',cute'] ['animal']
dogs and horse is a loyal animal ['dogs', 'horse'] ['animal','animal']
chicken layes eggs full of proteins ['chicken', 'eggs', 'proteins'] ['bird','food','food']
lion is the king of jungle ['lion', 'jungle'] ['animal', 'place']
PS: Because of space constraints here to make code pretty i dropped matchedName columns
t=kwx.Tag.tolist()#puts all strings in Tag into a list
dfx['term']=dfx.Title.str.split(' ')# Puts Title values into a list in a new colum term
dfx['term']=dfx['term'].map(lambda x: [*{*x} & {*t}])#Leverages sets to find strings both in t and term
dfx=dfx.assign(Tag=dfx.term)#creates a column called Tag
newdf=pd.merge(dfx.explode('Tag'),kwx).drop(columns=['Tag'])#Expands dfx to allow merging to kwx
newdf.groupby(['Title',newdf['term'].str.join(',')])['Area'].agg(list)#Groupby Title and term and add area to list
Title term
These cats are very cute cute,cats [nan, animal]
chicken layes eggs full of proteins proteins,chicken,eggs [food, bird, food]
dogs and horse is a loyal animal horse,dogs [animal, animal]
lion is the king of jungle jungle,lion [place, animal]
This question already has answers here:
Printing list elements on separate lines in Python
(10 answers)
Closed 2 years ago.
My list looks like this:
food_order = ['Spicy Chicken Sandwich', 'Chick-fil-A Waffle Potato Fries', 'Chic-fil-A Lemonade', 'Chocolate Chunk Cookie']
and I would like for it to look like:
Spicy Chicken Sandwich
Chick-fil-A Waffle PotatoFries
Chic-fil-A Lemonade
Chocolate Chunk Cookie
As simple as:
for x in food_order:
print(x)
Or if you want to print a new line after every item:
for x in food_order:
print(x+"\n")
You can join a list with new lines and print it:
food_order = ['Spicy Chicken Sandwich', 'Chick-fil-A Waffle Potato Fries', 'Chic-fil-A Lemonade', 'Chocolate Chunk Cookie']
print('\n\n'.join(food_order))
This will stick two new line characters between each of your list items and make a new string.
Result:
Spicy Chicken Sandwich
Chick-fil-A Waffle Potato Fries
Chic-fil-A Lemonade
Chocolate Chunk Cookie
Code:
food_order = ['Spicy Chicken Sandwich', 'Chick-fil-A Waffle Potato Fries',
'Chic-fil-A Lemonade', 'Chocolate Chunk Cookie']
for food in food_order:
print(food)
print('\n')
Output:
Spicy Chicken Sandwich
Chick-fil-A Waffle Potato Fries
Chic-fil-A Lemonade
Chocolate Chunk Cookie
A list of fruits with details in strings. I want to refine the core info, i.e. the fruit name from the strings.
Some of them have 1 word in name (e.g. Apple, Grape), some have 2 (Water melon, Start fruit).
I tried ngram way:
from nltk import ngrams
from collections import Counter
strings = [
"Apples Fresh Golden Delicious",
"Apples Fresh Red Delicious 12",
"Apple Sliced 12",
"Apple Diced 24",
"Water melon Fresh Petite Green on the turn",
"16 count Star fruit",
"8 count Star fruit",
"4 count Star fruit",
"Grapes Red Fresh Seedless",
"Grapes Green Fresh Seedless",
"Orange Naval Fresh 100 Count",
"Orange Naval Fresh 48 Count",
"Orange Naval Fresh 24 Count",
"Orange Naval Fresh 12 Count"]
basket = []
for s in strings:
grams = ngrams(s.split(), 1) # 2 for 2-gram
for g in grams:
basket.append("-".join(g))
print (Counter(basket))
1-gram:
Counter({'Fresh': 9, 'Orange': 4, 'Naval': 4})
2-gram:
Counter({'Orange-Naval': 4, 'Naval-Fresh': 4, 'count-Star': 3})
Obviously it's not working well.
What would be a better way? Thank you.
As stated in the title, I tried many ways and the closest I got till was here:
lyrics = ['A partridge in a pear tree','Two turtle doves, and','Three
French hens','Four colly birds','Five Gold Rings','Six geese a-
laying','Seven swans a-swimming','Eights maids a-milking','Nine ladies
dancing','Ten lords a-leaping','Elven piper piping','Twelve drummers
drumming']
days = ['first','second','third','fourth','fifth','Sixth','Seventh','Eighth','Nineth'
,'Tenth','Eleventh','Twelveth']
x=1
def base():
print("On the " + days[0] + " day of christmas my true love sent to me")
print(lyrics[0]+"\n")
def day_of_christmas(x):
try:
print("On the " + days[x] + " day of christmas my true love sent to me")
y = count_days(x)
day_of_christmas(y)
except IndexError:
return None
def count_days(day):
try:
print(str(lyrics[day]))
print(str(lyrics[day-1]))
print(str(lyrics[day-2]))
print(str(lyrics[day-3]))
print(str(lyrics[day-4]))
print(str(lyrics[day-5]))
print(str(lyrics[day-6]))
print(str(lyrics[day-7]))
print(str(lyrics[day-8]))
print(str(lyrics[day-9]))
print(str(lyrics[day-10]))
print(str(lyrics[day-11]+"\n"))
except IndexError:
return None
return day+1
base()
day_of_christmas(x)
My output is:
On the first day of christmas my true love sent to me
A partridge in a pear tree
On the second day of christmas my true love sent to me
Two turtle doves, and
A partridge in a pear tree
Twelve drummers drumming
Elven piper piping
Ten lords a-leaping
Nine ladies dancing
Eights maids a-milking
Seven swans a-swimming
Six geese a-laying
Five Gold Rings
Four colly birds
Three French hens
On the third day of christmas my true love sent to me
Three French hens
Two turtle doves, and
A partridge in a pear tree
Twelve drummers drumming
Elven piper piping
Ten lords a-leaping
Nine ladies dancing
Eights maids a-milking
Seven swans a-swimming
Six geese a-laying
Five Gold Rings
Four colly birds
On the fourth day of christmas my true love sent to me
Four colly birds
Three French hens
Two turtle doves, and
A partridge in a pear tree
Twelve drummers drumming
Elven piper piping
Ten lords a-leaping
Nine ladies dancing
Eights maids a-milking
Seven swans a-swimming
Six geese a-laying
Five Gold Rings
The output basically repeats itself(too long to display all) only the 12th day has correct output. I know I am forcing the 12 lines for each day and they are repeating due to the list negative index but I need to solve this problem without loops and if-else.
I expected the output(in this order till 12th day):
On the first day of christmas my true love sent to me
A partridge in a pear tree
On the second day of christmas my true love sent to me
Two turtle doves, and
A partridge in a pear tree
On the third day of christmas my true love sent to me
Three French hens
Two turtle doves, and
A partridge in a pear tree
On the fourth day of christmas my true love sent to me
Four colly birds
Three French hens
Two turtle doves, and
A partridge in a pear tree
I like #cricket_007's solution, but you can do it recursively too. This is a bit silly:
lyrics = [
("first", "A partridge in a pear tree"),
("second", "Two turtle doves, and"),
("third", "Three French hens"),
("fourth", "Four colly birds"),
("fifth", "Five Gold Rings")
]
def get_lyrics_for_day(n):
current_lyrics = [lyrics[n][1]]
if n != 0:
previous_lyrics = get_lyrics_for_day(n-1)
current_lyrics.extend(previous_lyrics)
return current_lyrics
def print_lyrics(iteration):
if iteration == len(lyrics):
return
all_lyrics = get_lyrics_for_day(iteration)
nth = lyrics[iteration][0]
print("\n".join([f"On the {nth} day of christmas my true love sent to me"] + all_lyrics), end="\n\n")
print_lyrics(iteration+1)
print_lyrics(0)
Output:
On the first day of christmas my true love sent to me
A partridge in a pear tree
On the second day of christmas my true love sent to me
Two turtle doves, and
A partridge in a pear tree
On the third day of christmas my true love sent to me
Three French hens
Two turtle doves, and
A partridge in a pear tree
On the fourth day of christmas my true love sent to me
Four colly birds
Three French hens
Two turtle doves, and
A partridge in a pear tree
On the fifth day of christmas my true love sent to me
Five Gold Rings
Four colly birds
Three French hens
Two turtle doves, and
A partridge in a pear tree
Use corecursion (fancy name for counting up from a staring point, rather than down to a base case), and catch the IndexError when you try to access days[12] in the call to sing_day(12) to stop.
def sing_day(n):
# This line raises an IndexError when n == 12
print("On the {} day of ...".format(days[n]))
print("\n".join(lyrics[n::-1]))
print()
sing_day(n+1) # Corecurse on the next day
def print_lyrics():
try:
sing_day(0) # Start the song, and keep going as long as you can
except IndexError:
pass # We got to sing_day(12), we can stop now.
print_lyrics()
Or, abuse list(map(...)) for the side effect of calling sing_day:
def sing_day(n):
print("On the ...")
print("\n".join(...))
print()
def print_lyrics():
list(map(sing_day, range(12)))
Construct a sequence of functions like so:
def the12th():
print("On the twelfth day...")
the11th()
def the11th():
print("On the eleventh day...")
the10th()
and so on. Then in your main, call them like this:
the1st()
the2nd()
the3rd()
and so on.
A loop from 0-12 would be prefered, but you can use list-slicing to get the lyrics, then join them on a newline.
def twelve_days(day):
print("On the {} day of christmas my true love sent to me".format(days[day]))
print('\n'.join(reversed(lyrics[:day+1])))
twelve_days(0)
twelve_days(1)
twelve_days(2)
twelve_days(3)
Output
On the first day of christmas my true love sent to me
A partridge in a pear tree
On the second day of christmas my true love sent to me
Two turtle doves, and
A partridge in a pear tree
On the third day of christmas my true love sent to me
Three French hens
Two turtle doves, and
A partridge in a pear tree
On the fourth day of christmas my true love sent to me
Four colly birds
Three French hens
Two turtle doves, and
A partridge in a pear tree
Note that day_of_christmas(y) within def day_of_christmas(x) is somewhat a loop... but doing recursion
Check out this
def print_lyrics(count):
print("On the " + days[count] + " day of christmas my true love sent to me")
print('\n'.join(lyrics[:count + 1]), end="\n")
print()
count = count + 1
if count < len(days):
print_poem(count)
count = 0
print_lyrics(count)