Ad

Creating Custom String From Two Lists

- 1 answer

I made a giveaway module and now I'm trying to create a function that returns a congratulations string for all the winners, using two lists like this.

winners = ["john", "anna", "max", "george"]
prizes = [(1, "apple"), (1, "pear"), (2, "carrots")]
# (number of these prize avaible, the prize)

They don't need to have the same length as you can see, but the sum of the numbers in prizes is always the same as the length in winners.

My ideal string would be something like.

"Congratulations to john for winning 1 apple, anna for winning 1 pear, and max and george for winning 1 carrot each."

I know I could probably expand the prize list and zip the two later but I'm really trying to keep the ones that have more than one winner grouped togheter. Because the list can be up to 100 prizes and sum(x[0] for x in prizes) winners.

This is what I've tried so far but it's not really useful when there are more than two winners per prize, and I don't really know a way to know when i'm in the last iteration to replace a , with an and.

winners = ["john", "anna", "max", "george"]
prizes = [(2, "peanuts"), (2, "carrot")]


def congratulations(winners, prizes):
    s = "Congratulations to "
    for w in winners:
        for p in prizes:
            s += "{} for winning {} {}, ".format(w, p[0], p[1])
            break
    return s


print(congratulations(winners, prizes))
#Congratulations to john for winning 2 peanuts, anna for winning 2 peanuts, max for winning 2 peanuts, george for winning 2 peanuts,

There are things I don't care though, like if a prize is written as plural or you need to add a , at the end. Thanks for any help.

Thanks to Henry I did some small amends but the code is the same.

winners = ["john", "anna", "max", "george", "carlos"]
prizes = [(1, "apple"), (3, "pears"), (1, "carrots")]


def congratulations(winners, prizes):
    s = "Congratulations to "
    i = 0
    for p in prizes:
        w = ", ".join(winners[i : i + p[0]])
        w = " and ".join(w.rsplit(", ", 1))
        s += "{} for winning {} {}{}; ".format(w, 1, p[1], "" if p[0] == 1 else " each")
        i += p[0]
    s = s[:-2] + "."
    k = s.rfind(";")
    s = s[:k] + "; and" + s[k + 1 :]
    return s


w = congratulations(winners, prizes)
print(w)
# Congratulations to john for winning 1 apple, anna, max and george for winning 1 pears each, and carlos for winning 1 carrots.
Ad

Answer

It should be better to loop over prizes list first, and place the winners in the string construction, for example:

winners = ["john", "anna", "max", "george"]
prizes = [(2, "peanuts"), (2, "carrot")]

def congratulations(winners, prizes):
    s = "Congratulations to "
    i = 0
    for p in prizes:
        w = ', '.join(winners[i: i + p[0]])
        s += "{} for winning {} {}{}, ".format(w, 1, p[1], '' if p[0]==1 else " each")
        i += p[0]

    return s


print(congratulations(winners, prizes))
# Congratulations to john, anna for winning 1 peanuts each, max, george for winning 1 carrot each, 

You'll need to amend the w pharse in case and is preferred instead of ,, for example:

w = ', '.join(winners[i: i + p[0]])
w = ' and '.join(w.rsplit(', ', 1))

It would replace the last occurance of ', ' by ' and ', the final string would look like Congratulations to john and anna for winning 1 peanuts each, max and george for winning 1 carrot each,

Ad
source: stackoverflow.com
Ad