Sequence(s) with str.join()

Raindrops
Raindrops in Python
def convert(number):
    drops = ["Pling","Plang","Plong"]
    factors = [3,5,7]
    sounds = ''.join(drops[index] for 
                     index, factor in 
                     enumerate(factors) if (number % factor == 0))

    return sounds or str(number)

This approach is very similar to the loop and f-string approach, but uses two lists to hold factors and sounds and enumerate() to extract an index. It also converts the loop that calculates the remainders and sounds into a generator expression within join(). Sounds is returned if it is not empty. Otherwise, a str version of the input number is returned.

This, like most approaches described here is O(1) time and space complexity. In benchmark timings, the generator-expression and multiple variables add a bit of overhead.

Readability here might not be the easiest for those not used to reading generator expressions inside calls to other functions, so if that is the case, this can be re-written as:

def convert(number):
   drops = ["Pling","Plang","Plong"]
   factors = [3,5,7]
   sounds = (drops[index] for index, factor in 
             enumerate(factors) if (number % factor == 0))

   return ''.join(sounds) or str(number)
4th Dec 2024 · Found it useful?

Other Approaches to Raindrops in Python

Other ways our community solved this exercise
def convert(num):
    sounds = ''

    if num % 3 == 0: sounds += 'Pling'
    if num % 5 == 0: sounds += 'Plang'
    if num % 7 == 0: sounds += 'Plong'

    return sounds or str(num)
if statements

Use a series of if statements and string concatenation.

def convert(number):
    sounds = ''
    drops = ("i", 3), ("a", 5), ("o", 7)

    for vowel, factor in drops:
        if number % factor == 0:
            sounds += f'Pl{vowel}ng'
    return sounds or str(number)
Loop and f-string

Loop through a tuple and assemble output via an f-string.

def convert(number):
    threes = '' if number % 3 else 'Pling'
    fives =  '' if number % 5 else 'Plang'
    sevens = '' if number % 7 else 'Plong'

    return f'{threes}{fives}{sevens}' or str(number)
Truthy and Falsey Values with f-strings

Use ternaries to build words and an f-string to assemble the result.

def convert(number):
    sounds = {3: 'Pling', 5: 'Plang', 7: 'Plong'}

    results = ''.join(sounds[divisor] for
                      divisor in sounds.keys()
                      if number % divisor == 0)

    return results or str(number)
Dict and str.join()

Use a dict to hold factors:values and str.join() with a generator-expression.

from itertools import compress

def convert(number):
    sounds ='Pling','Plang','Plong'
    mask =  ((number % factor) == 0 for factor in (3,5,7))
    return ''.join(compress(sounds, mask)) or str(number)
itertools.compress

Use itertools.compress() with a list mask.

from functools import reduce

def convert(number):
    sounds = ('Pling','Plang','Plong')
    factors = ((number % factor) == 0 for factor in (3,5,7))
    result = reduce(lambda sound, item : sound + (item[0] * item[1]), zip(sounds, factors), '')

    return result or str(number)
functools.reduce

Use functools.reduce() and zip().