Python List Comprehension: replace exactly one vowel with another vowel and generate word combinations

Viewed 92

I need help with using list comprehension to replace a vowel in a word with another vowel. The challenge is if the word contains multiple vowels -- if so, we need to just replace one vowel at a time.

Code and example below

import random
word = 'tame'
new_list = [["".join([random.choice(vowels) if c in 'aeiou' else c for c in word])] for c in range(len(word))]
print(new_list)

The output I get is

[['tumo'], ['tamo'], ['timu'], ['temo']]

My solution is replacing both vowels at the same time. The required output is to replace a single vowel (for tame, a is the first vowel and e is the second). So, there will be 4 replacements for a (e i o u) and 4 for e (a i o u). The result would be 8 word combinations like below

[['teme'], ['time'], ['tome'], ['tume'], ['tama'],['tami'], ['tamo'], ['tamu'] ]

I have tried out a couple recommendations (using re) but came up short. Getting a 'invalid syntax' or 'type error'. In general, I am wondering if we can apply multiple if conditions in a list compression?

Anyways, here are the variants that do not work

word = 'tame'
import re
result = []
new_list = [["".join([result.append(re.sub(c,v,word)) if c in 'aeiou' if v in 'aeiou' and c !=v else c for c in word])]]
print(result)

and

word = 'tame'
import re
result = []
new_list = [["".join([result.append(re.sub(c,v,word)) if c in 'aeiou' else c for c in word])] for v in 'aeiou' if c !=v]
print(result)

and

word = 'hate'
import re
result = []
new_list = [["".join([result.append(re.sub(c,v,word)) if c in 'aeiou' if v in 'aeiou' if c !=v  else c for c in word])]]
print(result)
2 Answers

It looks to me, you don't need random replacement, you want all possible combinations of the replaced vowels. Following this logic you could achieve that iterative:

word = 'tame'
vowels = 'aeiou'
res=[]
for idx, letter in enumerate(word):
    if letter in vowels:
        for vowel in vowels:
            w = word[:idx] + vowel + word[idx+1:]
            if w != word:
                res.append(w)
    
print(res)
['teme', 'time', 'tome', 'tume', 'tama', 'tami', 'tamo', 'tamu']

or as list comprehension:

word = 'tame'
vowels = 'aeiou'
res = [w for idx,letter in enumerate(word) if letter in vowels for vowel in vowels if (w:=word[:idx]+vowel+word[idx+1:]) != word]

I wouldn't recommend a list comprehension here since the readability decreases. Also note that you need python 3.8 and higher to use the walrus operator := like I did here in the list comprehension

Using regex module,

import re
vowels = 'aeiou'
word = 'tame'
result = []
for c in word:
    if c in vowels:
       for v in vowels:
          if c != v:
            result.append(re.sub(c, v, word))
print(result)

Output:

['teme', 'time', 'tome', 'tume', 'tama', 'tami', 'tamo', 'tamu']
Related