0

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)
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
gaurav8936
  • 43
  • 7

2 Answers2

0

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

Rabinzel
  • 7,757
  • 3
  • 10
  • 30
0

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']
Jitendra
  • 106
  • 3
  • thank you! Is there a way to do this with list comprehensions? – gaurav8936 Sep 17 '22 at 00:08
  • Nested for/if like this translate mechanically into list comprehensions. Move the appended expression `re.sub(c, v, word)` to the beginning, and then write the `for` and `if` clauses *in the original order*. Please see e.g. [Double iteration in list comprehension](https://stackoverflow.com/questions/1198777). – Karl Knechtel Sep 17 '22 at 02:11
  • Thanks @KarlKnechtel, I just updated my question with some thoughts on your suggestion. Am getting 'None' as the output -- and not the actual. I am missing something here. Will explore more ways – gaurav8936 Sep 17 '22 at 19:27
  • "I just updated my question with some thoughts on your suggestion." **Please do not do this**. If you have new code and a new problem, you have a new question. Stack Overflow is **not a discussion forum**, and your post is not a "thread" for figuring out your code project - it is a question that helps build a library of questions and answers, so other people can find what they need with a search engine. Please read [ask] and take the [tour] for details. – Karl Knechtel Sep 18 '22 at 07:55