2

I have a string from which I wish to extract vowels and consonants along with their indices.

I am thinking about :

a = "HELLO"
list_ = list(a)
vow = [(x, i) for i,x in enumerate(list_) if x in ['A', 'E', 'I', 'O', 'U']]
cons = [(x, i) for i, x in enumerate(list_) if x not in j for j in list_ if j in ['A', 'E', 'I', 'O', 'U']]

However, I am getting NameError (saying j is not defined). Why am I not able to nest my list comprehension.

My desired output :

vows : [('E', 1), ('O', 4)]
cons : [('H', 0), ('L', 2), ('L', 3)]
2
  • Maybe because you're using two list comprehension at once. Commented Oct 2, 2015 at 6:30
  • List comprehensions can be nested, there is something wrong about the way I am doing it Commented Oct 2, 2015 at 6:33

5 Answers 5

4

The issue with your second list comprehension is that ideally the if condition should go at the end (after the second for loop , only then j would we accessible). But you really do not need that, simply check if x is not in the list of vowels. Example -

cons = [(x, i) for i,x in enumerate(list_) if x not in ['A', 'E', 'I', 'O', 'U']]

Demo -

>>> a = "HELLO"
>>> list_ = list(a)
>>> vow = [(x, i) for i,x in enumerate(list_) if x in ['A', 'E', 'I', 'O', 'U']]
>>> cons = [(x, i) for i,x in enumerate(list_) if x not in ['A', 'E', 'I', 'O', 'U']]
>>> vow
[('E', 1), ('O', 4)]
>>> cons
[('H', 0), ('L', 2), ('L', 3)]

You can make this a bit faster by using set for vowels and you do not really need list_ , you can enumerate over a itself, and get exactly same result. Example -

vowel_set = {'A', 'E', 'I', 'O', 'U'}
vow = [(x, i) for i,x in enumerate(a) if x in vowel_set]
cons = [(x, i) for i,x in enumerate(a) if x not in vowel_set]

Demo -

>>> a = "HELLO"
>>> vowel_set = {'A', 'E', 'I', 'O', 'U'}
>>> vow = [(x, i) for i,x in enumerate(a) if x in vowel_set]
>>> cons = [(x, i) for i,x in enumerate(a) if x not in vowel_set]
>>> vow
[('E', 1), ('O', 4)]
>>> cons
[('H', 0), ('L', 2), ('L', 3)]
Sign up to request clarification or add additional context in comments.

Comments

2

The correct syntax would be to explicitely make the inner loop a list comprehension:

cons = [(x, i) for i, x in enumerate(list_) if x not in [ j for
            j in list_ if j in ['A', 'E', 'I', 'O', 'U']]]

But here the correct way to get consonants would be simply (as already said by others):

cons = [(x, i) for i,x in enumerate(list_) if x not in ['A', 'E', 'I', 'O', 'U']]

Comments

2

Rule #1 about nested LCs in Python: The outer loop goes first.

cons = [(x, i) for j in list_ if j in ['A', 'E', 'I', 'O', 'U'] for i, x in enumerate(list_) if x not in j]

But this will give the wrong result since you should just be using not in in the first place instead.

Comments

2

You're over-complicating it

a = "HELLO"
list_ = list(a)
vow = [(x, i) for i,x in enumerate(list_) if x in ['A', 'E', 'I', 'O', 'U']]
cons = [(x, i) for i, x in enumerate(list_) if x not in ['A', 'E', 'I', 'O', 'U']]

See Anand S Kumar's answer for details :)


The mistake in your nesting is that you need to nest it again

cons = [(x, i) for i, x in enumerate(list_) if x not in [j for j in list_ if j in ['A', 'E', 'I', 'O', 'U']]]

Comments

2

You can check for membership in a string:

>>> 'I' in 'AEIOU'
True

You could convert each character in a string to a member of a set, for slightly faster searching:

>>> 'Z' in set('AEIOU')
False

You don't need the second inner loop:

>>> vowels = set('AEIOU')
>>> vows = [(char, index) for index, char in enumerate(word) if char in vowels]
>>> cons = [(char, index) for index, char in enumerate(word) if char not in vowels]

2 Comments

But how can you also get indices this way ? if 'L' in 'HELLO': print 'HELLO'.find('L') This will only give the index of the first occurrence of L (here 2)
My distinction is to check against a string of vowels rather than a list of vowels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.