This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 7 years ago.
def anti_vowel(text):
upper_vowels = ['A', 'E', 'I', 'O', 'U']
lower_vowels = ['a', 'e', 'i', 'o', 'u']
char_list = list(text)
for char in char_list:
if char in upper_vowels or char in lower_vowels:
char_list.remove(char)
new_word = ''
for char in char_list:
new_word += char
return new_word
If I pass anti_vowel("Hey look Words!"), I get the result 'Hy lk Words!'. The 'o' in 'Words!' is not removed.
As others have noted, you're modifying the list while you iterate over it. That's not going to work: the list changes size while you iterate, causing you to skip over some characters. You could use a list copy to avoid this, but maybe consider just using a better approach.
You can build the string up character-by-character, instead:
def anti_vowel(text):
vowels = 'AEIOUaeiou'
result = []
for c in text:
if c not in vowels:
result.append(c)
return ''.join(result)
This is faster, safer, shorter and easier to read than the original approach.
Alternately, you can use Python's powerful built-in string functions to do this very simply:
def anti_vowel(text):
return text.translate(dict.fromkeys(map(ord, 'aeiouAEIOU')))
This pushes the text through a translation table that deletes all the vowels. Easy!
Few things going on here.
Never modify lists while iterating through them. Your could create a simple copy by calling list[:] instead if you'd to continue using your technique.
Use list comprehension to simplify your code further.
Simplifying the code a bit:
def anti_vowel(text):
upper_vowels = ['A', 'E', 'I', 'O', 'U']
lower_vowels = [s.lower() for s in upper_vowels]
char_list = list(text)
for char in char_list[:]:
if char in upper_vowels or char in lower_vowels:
char_list.remove(char)
return ''.join(char_list)
If you want to simplify everything under a single lambda then use the following:
anti_vowel = lambda text: ''.join([s for s in text if s.upper() not in ['A', 'E', 'I', 'O', 'U']])
You can call it like regular function anti_vowel(). The idea behind it as follows:
Iterate through every character, taking the upper case
Use list comprehension to create a new list out of those characters, only if they do not exist in the vowels. ([x for x in list])
Finally put the characters together (''.join([])
Related
My purpose is to get an input as a string and return a list of lower case letters of that string, without repeats, without punctuations, in alphabetical order. For example, the input "happy!" would get ['a','h','p','y']. I try to use the join function to get rid of my punctuations but somehow it doesn't work. Does anybody know why? Also, can sort.() sort alphabets? Am I using it in the right way? Thanks!
def split(a):
a.lower()
return [char for char in a]
def f(a):
i=split(a)
s=set(i)
l=list(s)
v=l.join(u for u in l if u not in ("?", ".", ";", ":", "!"))
v.sort()
return v
.join() is a string method, but being used on a list, so the code raises an exception, but join and isn't really needed here.
You're on the right track with set(). It only stores unique items, so create a set of your input and compute the intersection(&) with lower case letters. Sort the result:
>>> import string
>>> s = 'Happy!'
>>> sorted(set(s.lower()) & set(string.ascii_lowercase))
['a', 'h', 'p', 'y']
You could use:
def f(a):
return sorted(set(a.lower().strip('?.;:!')))
>>> f('Happy!')
['a', 'h', 'p', 'y']
You could also use regex for this:
pattern = re.compile(r'[^a-z]')
string = 'Hello# W0rld!!##'
print(sorted(set(pattern.sub('', string))))
Output:
['d', 'e', 'l', 'o', 'r']
For those that don't know, replacing vowels with 'ooba' has become a popular trend on https://reddit.com/r/prequelmemes . I would like to automate this process by making a program with python 2.7 that replaces vowels with 'ooba'. I have no idea where to get started
You could use a simple regular expression:
import re
my_string = 'Hello!'
my_other_string = re.sub(r'[aeiou]', 'ooba', my_string)
print(my_other_string) # Hooballooba!
Following method is suggested if the line is short. I would prefer using regex otherwise. Following assumes that your text is s.
s = ''.join(['ooba' if i in ['a', 'e', 'i', 'o', 'u'] else i for i in s])
Regex approach:
import re
s = re.sub(r'a|e|i|o|u', "ooba", s)
For a quick and simple answer, you could feed string meme into here
for i, c in enumerate(meme):
if c in ['a', 'e', 'i', 'o', 'u']:
meme[:i] = meme[:i] + 'ooba' + meme[i+1:]
It goes over each character in the string, and checks if it is a vowel. If it is, it slices around the index and inserts 'ooba' where it used to be.
I am creating a function in order to develop a tiny word game. When I was creating it I got stuck when I tried to write the body. I was looking for information about Python and if I can write a return statement . It seems that it is possible but I didn't find out anything clear about that. This is my body function: This is my current progress: Am I close? or Should I try another method?
def num_words_on_board(board, words):
""" (list of list of str, list of str) -> int
Return how many words appear on board.
>>> num_words_on_board([['A', 'N', 'T', 'T'], ['X', 'S', 'O', 'B']], ['ANT', 'BOX', 'SOB', 'TO'])
3
"""
count = 0
for word_list in board:
if words in ''.join(word_list):
count = count + 1
return count
Your question is lacking in explanation, but I'll answer the best I understood.
I think you are trying to do something like a wordsearch solver, mixed with a scramble puzzle?
Anyways, my recommendation is to make multiple functions for everything you need to solve. For example:
The way I see it, you need to know if the letters in the board can make up each of the words in the words variable. That can be done by one function. If you don't really need the order of the word, just the length, then we can do it like this.
def same (word, letters):
temp = []
for every_letter in word:
if every_letter in letters and every_letter not in temp:
temp.append(every_letter)
return len(temp) >= len(word)
This function takes only one word and a "bunch of letters" (for example a list from board ;) ) as parameters, then the function compares each letter in the word against each letter in the "bunch of letters" and if it finds a match it adds it to a temp variable, at the end of the iterations if the temp variable has at least the same count of letters as the initial `word' then it's safe to say that the word can be built.
*there is a problem with this function. If the original word has repeated letters, for example the word "butter" then this function will not work, but since this is not your case we are good to continue.
For the second part we have to use that function for every word in board so we'll use another function for that:
def num_words_on_board(board, words):
count = 0
for word in words:
for letters in board:
if same(word, letters):
count += 1
print(count) # This is not needed, just here for testing.
return count
And there we go. This function should return the count which is 3. I hope this helps you.
(if anyone wanna correct my code please feel free, it's not optimal by any means. Just thought it would be easy to understand like this, rather than the answer in the duplicate question mentioned by Stefan Pochmann)
:)
I had a previous function can I use it in order to create this new one?.
My previous function is this:
def board_contains_word(board, word):
""" (list of list of str, str) -> bool
Return True if and only if word appears in board.
Precondition: board has at least one row and one column.
>>> board_contains_word([['A', 'N', 'T', 'T'], ['X', 'S', 'O', 'B']], 'ANT')
True
>>> board_contains_word([['A', 'N', 'T', 'T'], ['X', 'S', 'O', 'B']], 'NNT')
False
>>> board_contains_word([['A', 'N', 'T', 'T'], ['X', 'S', 'O', 'B']], 'NTT')
True
"""
for word_list in board:
if word in ''.join(word_list):
return True
return False
This question already has answers here:
Elegant Python function to convert CamelCase to snake_case?
(30 answers)
Closed 6 years ago.
how can i change string using for-loop without regex.
example : (python 2.7.1)
import re
trans = lambda src: re.sub("([A-Z])", lambda m:"_"+m.group().lower(), src, flags=0)
print(trans("helloWorld"))
i expect to result as :
hello_world
i want to change from regex version into for-loop version.
conditions
the result will be the same
just one line!
using for loop
def change(string):
for letter in string:
if letter.isupper():
yield '_{}'.format(letter.lower())
else:
yield letter
print ''.join(change("helloWorld"))
If you want to have it in one line:
print ''.join(letter.isupper() and '_{}'.format(letter.lower()) or letter for letter in 'helloWorld')
You may achieve it using list comprehension (i.e one liner for loop) as:
>>> my_string = "helloWorld"
>>> ''.join(['_{}'.format(s.lower()) if s.isupper() else s for s in my_string])
'hello_world'
Explanation:
List is nothing but a list of chars. Iterate over each char and check whether it is upper case character using isupper() fuct. If it is, replace it to _<lower-case> using lower() func.
The result of above list comprehension is: ['h', 'e', 'l', 'l', 'o', '_w', 'o', 'r', 'l', 'd']. Join the list to find your string i.e. hello_world
The program identifies if one of the elements in the string word is a consonant by looping though the word string, and then for each iteration though the word string, iterating though the consonants list and comparing if the current element in word string equals to the current element of consonant list.
If yes, the current element of the word string is a consonant and the consonant gets printed (not the index of the consonant, but the actual consonant, for e.g. "d".)
The problem is, I get this instead:
1
1
What am I doing wrong? Shouldn't the nested loops work so that the below loop iterates every element for each element in the above loop? That is, each index above makes the below loop iterate though each index?
That's the program:
word = "Hello"
consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'z']
for character in range(len(word)):
for char in range(len(consonants)):
if consonants[char] == word[character]:
consonant = word[character]
print consonant
You are misreading the output. The character is the letter L lowercase, not the number 1.
In other words, your code is working as designed. The captital letter H is not in your consonants list, but the two lowercase letters l in Hello are.
Note that it'd be much more efficient to use a set for consonants here; you'd not have to loop over that whole list and just use in to test for membership. That works with lists too, but is much more efficient with a set. If you lowercase the word value you'd also be able to match the H.
Last but not least, you can loop over the word string directly rather than use range(len(word)) then use the generated index:
word = "Hello"
consonants = set('bcdfghjklmnpqrstvwxz')
for character in word.lower():
if character in consonants:
print character
Demo:
>>> word = "Hello"
>>> consonants = set('bcdfghjklmnpqrstvwxz')
>>> for character in word.lower():
... if character in consonants:
... print character
...
h
l
l