Reputation: 2233
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)]
Upvotes: 2
Views: 1025
Reputation: 24133
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]
Upvotes: 2
Reputation: 148880
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']]
Upvotes: 2
Reputation: 90879
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)]
Upvotes: 4
Reputation: 3973
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']]]
Upvotes: 2
Reputation: 798526
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.
Upvotes: 2