I am trying to write a function that accepts a string (sentence) and then cleans it and returns all alphabets, numbers and a hypen. however the code seems to error. Kindly know what I am doing wrong here.
Example: Blake D'souza is an !d!0t
Should return: Blake D'souza is an d0t
Python:
def remove_unw2anted(str):
str = ''.join([c for c in str if c in 'ABCDEFGHIJKLNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890\''])
return str
def clean_sentence(s):
lst = [word for word in s.split()]
#print lst
for items in lst:
cleaned = remove_unw2anted(items)
return cleaned
s = 'Blake D\'souza is an !d!0t'
print clean_sentence(s)
You only return last cleaned word!
Should be:
def clean_sentence(s):
lst = [word for word in s.split()]
lst_cleaned = []
for items in lst:
lst_cleaned.append(remove_unw2anted(items))
return ' '.join(lst_cleaned)
A shorter method could be this:
def is_ok(c):
return c.isalnum() or c in " '"
def clean_sentence(s):
return filter(is_ok, s)
s = "Blake D'souza is an !d!0t"
print clean_sentence(s)
A variation using string.translate which has the benefit ? of being easy to extend and is part of string.
import string
allchars = string.maketrans('','')
tokeep = string.letters + string.digits + '-'
toremove = allchars.translate(None, tokeep)
s = "Blake D'souza is an !d!0t"
print s.translate(None, toremove)
Output:
BlakeDsouzaisand0t
The OP said only keep characters, digits and hyphen - perhaps they meant keep whitespace as well?
Related
def cat_latin_word(text):
""" convert the string in another form
"""
constant = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"
for word in text.split():
if word[0] in constant:
word = (str(word)[-1:] + str(word)[:4] + "eeoow")
else:
word = (str(word) + "eeoow")
print(word)
def main():
""" converts"""
text = input("Enter a sentence ")
cat_latin_word(text)
main()
A few pointers:
Converting your code to "one line" doesn't make it better.
No need to type out all consonants, use the string module and use set for O(1) lookup complexity.
Use formatted string literals (Python 3.6+) for more readable and efficient code.
No need to use str on variables which are already strings.
For a single line, you can use a list comprehension with a ternary statement and ' '.join.
Here's a working example:
from string import ascii_lowercase, ascii_uppercase
def cat_latin_word(text):
consonants = (set(ascii_lowercase) | set(ascii_uppercase)) - set('aeiouAEIOU')
print(' '.join([f'{word}eeow' if not word[0] in consonants else \
f'{word[-1:]}{word[:4]}eeoow' for word in text.split()]))
text = input("Enter a sentence ")
cat_latin_word(text)
You may use a list to put all the words or use print() in a different way.
Example:
print(word, end="\t")
where here I use the keyword argument end to set it to '\t' ( by default is '\n')
Simply edited your code to return the results as a words separated by space.
def cat_latin_word(text):
constant = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"
result = []
for word in text.split():
if word[0] in constant:
word = (str(word)[-1:] + str(word)[:4] + "eeoow")
result.append(word)
else:
word = (str(word) + "eeoow")
result.append(word)
return ' '.join(result)
def main():
text = 'ankit jaiswal'
print(cat_latin_word(text))
def convert_pig_latin(pig):
first_letter = pig[0]
#Check if Vowel
if first_letter in 'aeiou':
pig_word = pig + 'ay'
else:
pig_word = pig[1:] + first_letter + 'ay'
print('Pig Latin:',pig_word)
So basically, this only works for 1 single word input. Let's say the user enters a sentence, it won't work which is obvious. This code is in my functions tab, and my main module of course runs it with an input sentence given. Could someone please help me out how it'll take a whole sentence instead of just one word -.- Tried using a for loop but messed it up.
Appreciate it, thanks!
You could use a list comprehension here:
def pig_latin(sentence):
return ' '.join([s + 'ay' if s[0] in 'aeiou' else s[1:] + s[0] + 'ay' for s in sentence.split()])
print(pig_latin("convert all the words"))
Output:
onvertcay allay hetay ordsway
You could also keep your current approach where the function converts a single word, and use map():
>>> def pig_latin_word(s):
... return s + 'ay' if s[0] in 'aeiou' else s[1:] + s[0] + 'ay'
...
>>> ' '.join(map(pig_latin_word, "convert all the words".split()))
'onvertcay allay hetay ordsway'
>>>
Convert the string into a list of strings:
words = pig.split(' ')
Then you would run a for loop on the list:
for word in words:
#run your conversation code on each word
Then join the list back into a string:
pig = ' '.join(words)
This question already has answers here:
How can I invert (swap) the case of each letter in a string?
(8 answers)
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed 6 months ago.
I would like to change the chars of a string from lowercase to uppercase.
My code is below, the output I get with my code is a; could you please tell me where I am wrong and explain why?
Thanks in advance
test = "AltERNating"
def to_alternating_case(string):
words = list(string)
for word in words:
if word.isupper() == True:
return word.lower()
else:
return word.upper()
print to_alternating_case(test)
If you want to invert the case of that string, try this:
>>> 'AltERNating'.swapcase()
'aLTernATING'
There are two answers to this: an easy one and a hard one.
The easy one
Python has a built in function to do that, i dont exactly remember what it is, but something along the lines of
string.swapcase()
The hard one
You define your own function. The way you made your function is wrong, because
iterating over a string will return it letter by letter, and you just return the first letter instead of continuing the iteration.
def to_alternating_case(string):
temp = ""
for character in string:
if character.isupper() == True:
temp += character.lower()
else:
temp += word.upper()
return temp
Your loop iterates over the characters in the input string. It then returns from the very first iteration. Thus, you always get a 1-char return value.
test = "AltERNating"
def to_alternating_case(string):
words = list(string)
rval = ''
for c in words:
if word.isupper():
rval += c.lower()
else:
rval += c.upper()
return rval
print to_alternating_case(test)
That's because your function returns the first character only. I mean return keyword breaks your for loop.
Also, note that is unnecessary to convert the string into a list by running words = list(string) because you can iterate over a string just as you did with the list.
If you're looking for an algorithmic solution instead of the swapcase() then modify your method this way instead:
test = "AltERNating"
def to_alternating_case(string):
res = ""
for word in string:
if word.isupper() == True:
res = res + word.lower()
else:
res = res + word.upper()
return res
print to_alternating_case(test)
You are returning the first alphabet after looping over the word alternating which is not what you are expecting. There are some suggestions to directly loop over the string rather than converting it to a list, and expression if <variable-name> == True can be directly simplified to if <variable-name>. Answer with modifications as follows:
test = "AltERNating"
def to_alternating_case(string):
result = ''
for word in string:
if word.isupper():
result += word.lower()
else:
result += word.upper()
return result
print to_alternating_case(test)
OR using list comprehension :
def to_alternating_case(string):
result =[word.lower() if word.isupper() else word.upper() for word in string]
return ''.join(result)
OR using map, lambda:
def to_alternating_case(string):
result = map(lambda word:word.lower() if word.isupper() else word.upper(), string)
return ''.join(result)
You should do that like this:
test = "AltERNating"
def to_alternating_case(string):
words = list(string)
newstring = ""
if word.isupper():
newstring += word.lower()
else:
newstring += word.upper()
return alternative
print to_alternating_case(test)
def myfunc(string):
i=0
newstring=''
for x in string:
if i%2==0:
newstring=newstring+x.lower()
else:
newstring=newstring+x.upper()
i+=1
return newstring
contents='abcdefgasdfadfasdf'
temp=''
ss=list(contents)
for item in range(len(ss)):
if item%2==0:
temp+=ss[item].lower()
else:
temp+=ss[item].upper()
print(temp)
you can add this code inside a function also and in place of print use the return key
string=input("enter string:")
temp=''
ss=list(string)
for item in range(len(ss)):
if item%2==0:
temp+=ss[item].lower()
else:
temp+=ss[item].upper()
print(temp)
Here is a short form of the hard way:
alt_case = lambda s : ''.join([c.upper() if c.islower() else c.lower() for c in s])
print(alt_case('AltERNating'))
As I was looking for a solution making a all upper or all lower string alternating case, here is a solution to this problem:
alt_case = lambda s : ''.join([c.upper() if i%2 == 0 else c.lower() for i, c in enumerate(s)])
print(alt_case('alternating'))
You could use swapcase() method
string_name.swapcase()
or you could be a little bit fancy and use list comprehension
string = "thE big BROWN FoX JuMPeD oVEr thE LAZY Dog"
y = "".join([val.upper() if val.islower() else val.lower() for val in string])
print(y)
>>> 'THe BIG brown fOx jUmpEd OveR THe lazy dOG'
This doesn't use any 'pythonic' methods and gives the answer in a basic logical format using ASCII :
sentence = 'aWESOME is cODING'
words = sentence.split(' ')
sentence = ' '.join(reversed(words))
ans =''
for s in sentence:
if ord(s) >= 97 and ord(s) <= 122:
ans = ans + chr(ord(s) - 32)
elif ord(s) >= 65 and ord(s) <= 90 :
ans = ans + chr(ord(s) + 32)
else :
ans += ' '
print(ans)
So, the output will be : Coding IS Awesome
Shift word to right and then reverse it.
You should take a word shift to right and reverse it then return as follows:
>>> shift_reverse('Introduction to Computer Programming')
gnimmargorP noitcudortnI ot retupmoC
I tried using this method to find the above answer but it doesnt seem to work
Please help :(
s= "I Me You"
def shift_reverse(s):
l= s.split()
new_str= ' '.join(l[-1:] + l[:-1])
new_str = new_str[::-1]
return (new_str)
print (shift_reverse(s))
but the print i get is
[evaluate untitled-3.py]
eM I uoY
You need to reverse each of the re-ordered list:
reordered = l[-1:] + l[:-1]
new_str = ' '.join(word[::-1] for word in reordered)
You can join a generator expression that generates reversed words in the rotated split list:
>>> s = 'Introduction to Computer Programming'
>>> ' '.join(w[::-1] for w in (lambda l: l[-1:] + l[:-1])(s.split()))
'gnimmargorP noitcudortnI ot retupmoC'
Here is a step by step with the functions:
Create shift function to move last word to beginning:
def shift(sentence):
words = sentence.split()
return ' '.join([words[-1]] + words[:-1])
Create reverse function to reverse all words in a sentence (uses list comprehension):
def reverse(sentence):
return ' '.join([word[::-1] for word in sentence.split()])
Create shift_reverse to reverse all words and then shift the last on to the start:
def shift_reverse(sentence):
return shift(reverse(sentence))
Result:
shift_reverse('Introduction to Computer Programming')
Output:
'gnimmargorP noitcudortnI ot retupmoC'
In new_str = new_str[::1], you're reversing the entire string, character per character.
ghi abc def
fed cba ihg
You have to reverse each word in the list of words.
def shift_reverse(string):
words = string.split()
shifted_words = [words[-1]] + words[:-1]
return ' '.join([word[::-1] for word in shifted_words])
You can shift the string over, the reverse each item:
>>> phrase = 'Introduction to Computer Programming'
>>> new = ' '.join([word[::-1] for word in [phrase.split()[-1]]+phrase.split()[:-1]])
>>> print new
gnimmargorP noitcudortnI ot retupmoC
>>>
def shift_reverse(s):
rev = ["".join(reversed(word)) for word in s.split(" ")]
return "{} {}".format(rev.pop(), " ".join(rev))
reverse all the strings, pop the last off the list of reversed words and join the remainder.
This should work for you
s= "Introduction to Computer Programming"
def shift_reverse(s):
l= s.split()
l = [l.pop()]+ l
return ' '.join(i[::-1] for i in l)
print (shift_reverse(s))
output:
gnimmargorP noitcudortnI ot retupmoC
def split_on_separators(word, separators):
"""
Return a list of non-empty, non-blank strings from the original string
determined by splitting the string on any of the separators.
separators is a string of single-character separators.
>>> split_on_separators("Wow! Fantastic, you're done.", "!,")
['Wow', ' Fantastic', " you're done."]
"""
word_list = []
for ch in word.split():
stripped = ch.strip(separators)
word_list.append(stripped)
return word_list
#output
['Wow', 'Fantastic', "you're", 'done.']
The separators are removed but I can't seem to get the white space in front of the F. Secondly 'you're done.' is not in a single string
Any Help would be greatly appreciated :)
I'm using python 3
One solution could be:
def split_on_separators(word, separators):
word_list = [word]
auxList = []
for sep in separators:
for w in word_list:
auxList.extend(w.split(sep))
word_list = auxList
auxList = list()
return word_list
Out[76]: ['Wow', ' Fantastic', " you're done."]
This should do the job:
def split_on_separators(word, separators):
for sep in separators:
word = word.replace(sep, '^#^')
return [x.strip() for x in word.split('^#^')]
The ^#^ is just a placeholder. I made it a weird character combination to make sure it doesn't appear in a normal sentence. You can replace it, if you want.
Another crazy solution:
import itertools
def split_on_separators(word, separators):
groups = itertools.groupby(word, lambda char: char in separators)
return [''.join(letters) for is_sep, letters in groups if not is_sep]
For the case where two separators can be adjacent (and you want to represent it as an empty word):
import itertools
def split_on_separators(word, separators):
groups = itertools.groupby(word, lambda char: char in separators)
seps2words = lambda letters: [''] * (len(tuple(letters)) - 1)
return [word for is_sep, letters in groups
for word in ([''.join(letters)] if not is_sep else seps2words(letters))]
You're splitting prior to stripping it. Splitting is done based on whitespace between words; therefore, you won't see it in your final output. That is also the reason "you're done" is not a single string. It splits it based on white space between the words.
You might try a delimiter for the split:
str.split([sep[, maxsplit]]) Return a list of the words in the string,
using sep as the delimiter string.