How to remove neighbouring letter if they are the same using enumerate? - python

I'm trying to solve this exercise using enumerate, but I don't have any idea how to implement the value. In a mathematical way I said if for index and index+1 letter is the same do nothing, if the upcoming letter is different write letter. But I have no idea how to do it in python
Desired result aaabbbaas => abas.
def zad6(string):
b =""
for index,letter in enumerate(string):
if letter[index] == letter[index+1]:
b += None
else:
b += letter
return b
print(zad6("aaabbbaas"))

Here is a fix of your code using enumerate, you can check if each previous letter was the same, except the first time (index == 0):
def zad6(string):
for index, letter in enumerate(string):
if index == 0:
b = letter
elif letter != string[index-1]:
b += letter
return b
print(zad6("Baabba"))
output: 'Baba'
NB. this considers case, 'B' and 'b' will be different, if you want to ignore case use letter.lower() != string[index-1].lower()
alternative
just for the sake of showing an efficient solution, in real life you could use itertools.groupby:
from itertools import groupby
string = "Baabba"
''.join(l for l,_ in groupby(string))

Only append when you have something to append, there's no need to append None (and in fact, it doesn't work). Also, you should check if there's a next character at all in the string, or it will fail at the last iteration
def zad6(string):
b = ""
for index,letter in enumerate(string):
if index == len(string)-1 or letter != string[index+1]:
b+=letter
return b
print(zad6("Baabba"))

Here's an alternate approach without using a for loop, that seems a bit simpler:
from operator import itemgetter
def zad6(string):
filt = filter(lambda x: x[1] != string[x[0] - 1], enumerate(string))
return ''.join(map(itemgetter(1), filt))
assert zad6('aaabbbaas') == 'abas'
assert zad6('Baabba') == 'Baba'

Related

remove consecutive substrings from a string without importing any packages

I want to remove consecutive "a" substrings and replace them with one "a" from a string without importing any packages.
For example, I want to get abbccca from aaabbcccaaaa.
Any suggestions?
Thanks.
This method will remove a determined repeated char from your string:
def remove_dulicated_char(string, char):
new_s = ""
prev = ""
for c in string:
if len(new_s) == 0:
new_s += c
prev = c
if c == prev and c == char:
continue
else:
new_s += c
prev = c
return new_s
print(remove_dulicated_char("aaabbcccaaaa", "a"))
Whats wrong with using a loop?
oldstring = 'aaabbcccaaaa'
# Initialise the first character as the same as the initial string
# as this will always be the same.
newstring = oldstring[0]
# Loop through each character starting at the second character
# check if the preceding character is an a, if it isn't add it to
# the new string. If it is an a then check if the current character
# is an a too. If the current character isn't an a then add it to
# the new string.
for i in range(1, len(oldstring)):
if oldstring[i-1] != 'a':
newstring += oldstring[i]
else:
if oldstring[i] != 'a':
newstring += oldstring[i]
print(newstring)
using python regular expressions this will do it.
If you don't know about regex. They are extremely powerful for
this kind of matching
import re
str = 'aaabbcccaaaa'
print(re.sub('a+', 'a', str))
You can use a function that removes double values of a string occurrence recursively until only one occurrence of the repeating string remains:
val = 'aaabbcccaaaaaaaaaaa'
def remove_doubles(v):
v = v.replace('aa', 'a')
if 'aa' in v:
v = remove_doubles(v)
if 'aa' in v:
v = remove_doubles(v)
else: return v
else: return v
print(remove_doubles(val))
There are many ways to do this. Here's another one:
def remove_duplicates(s, x):
t = [s[0]]
for c in s[1:]:
if c != x or t[-1] != x:
t.append(c)
return ''.join(t)
print(remove_duplicates('aaabbcccaaaa', 'a'))

Return the number of times that the string "hi" appears anywhere in the given string -- Python codingbat problem

I'm aware that I can use the .count() function for this, but I tried to do this with a for loop and I keep getting a compile error in line 6. Does anyone see what's wrong with this code and why it wouldn't give the same output? Thanks in advance!
def count_hi(string):
# Create an empty list to add to
num_hi = []
# for every index in string , if the character is h and the next is i,
# add element to list
for index in string:
if string[index] == 'h' AND string[index + 1] == 'i':
num_hi.append('hi found')
return len(num_hi) # return length of list
Why not use count?
def count_hi(string):
return string.count('hi')
Fix for your code:
def count_hi(string):
count = 0
for i in range(1, len(string)):
if string[i - 1] == 'h' and string[i] == 'i':
count += 1
return count
Python is case sensitive, not AND but and.
Appending to list and counting it is a lot of overhead, you should just use a variable and increment it every time you find hi.
Instead of enumerate, you can use range to start from index 1 and check your string from i - 1 and 1. Avoids another check.
I'd prefer the previous solution using .count(). Why to write code when there is a built-in method for you?
See Harshal Parekh's Asnwer, it provides a better analysis and explanation.
When you iterate over a string, you're not iterating over indexes, but over the letters themselves. A quick fix for this could be:
def count_hi(string):
num_hi = []
# for every index in string , if the character is h and the next is i, add element to list
for index, _character in enumerate(string):
if index == len(string) - 1:
break # on the last one, you'd get an index error.
if string[index] == 'h' and string[index + 1] == 'i': # "and", not "AND"
num_hi.append('hi found')
return len(num_hi) # return length of list
The simplest way to do this is to use the builtin collection module.
from collections import Counter
def count_hi(string):
counts = Counter(string.split())
return print(counts['hi'])
You can try this, it should do the trick.
def count_hi(str):
counter = 0
str.lower()
str.replace(' ', '')
for i in range(0, len(str)-1):
if str[i] == 'h' and str[i+1] == 'i':
counter += 1
return counter
My solution:
def count_hi(str):
sum = 0
for i in range(len(str)-1):
if str[i:(i+2)] == "hi":
sum += 1
return sum

How to make a for loop iterate through each item in a string with an if statement?

I'm trying to make a function that takes in a string from a user and then outputs the same string. However for each letter in an even position it outputs the corresponding lower case letter, and for each letter in an odd position it outputs the corresponding uppercase letter. Keep in mind only one word will be passed through it at a time.
I've tried to create a for loop with an if statement nested within it, but so far, the for loop stops after iterating through the first letter. My code is below:
def converter(string):
for letters in string:
if len(letters) % 2 == 0:
return letters.lower()
elif len(letters)% 2 != 0:
return letters.upper()
When I run the code:
converter('app')
The output I get is 'A'
The expected output should be 'aPp'
The first thing you need to know is that in Python, strings are immutable. So "modifying" a string means you have to build a new string from scratch in (here, I call that newstring).
Second, you are misunderstanding the loop. You are saying for letters in string. This loop iterates over each letter of the string. On the first iteration, letters is the first letter of the strong. You then convert it to upper case (since the length of a single letter is always 1), and return it. You aren't reaching the rest of the letters! In the code below, I change the plurality to just letter to make this idea clear.
This amends all of those problems:
def converter(string):
newstring = ""
for i, letter in enumerate(string):
if i % 2 == 0:
newstring += letter.lower()
elif i % 2 != 0:
newstring += letter.upper()
return newstring
This can be boiled down to a nice list comprehension:
def converter(string):
return "".join([letter.lower() if i % 2 == 0 else letter.upper()
for i, letter in enumerate(string)])
In [1]: def converter(string):
...: return ''.join([j.upper() if i % 2 == 1 else j.lower() for i, j in enumerate(string)])
In [2]: converter('apple')
Out[2]: 'aPpLe'
''.join([s.lower() if c % 2 == 0 else s.upper() for c, s in enumerate('apple')])
# returns 'aPpLe'
first check for the condition, then iterate through the string using the nice old enumerate built-in.

How to change case for alternative letters of a string

I would like to convert every other letter of a string into uppercase. For example provided the input is 'ahdjeryu', the result should be 'AhDjErYu'.
I was trying this:
def mycode(letters):
myword = letters.split()
for i in letters:
if i%2 == 0:
return i.upper()
else:
return i.lower()
print(mycode('ahdjeryu'))
The error thrown as:
if i%2==0:
TypeError: not all arguments converted during string formatting
Several issues with your code:
You only need to use str.split to remove whitespace. Here, not necessary.
To extract the index of a letter as well as the letter, use enumerate.
return will return just one letter. You can instead yield letters and then use str.join on the generator.
Here's a working example:
def mycode(letters):
for idx, i in enumerate(letters):
if idx % 2 == 0:
yield i.upper()
else:
yield i.lower()
print(''.join(mycode('ahdjeryu')))
AhDjErYu
The above logic can be equivalently implemented via a generator comprehension:
res = ''.join(i.upper() if idx % 2 == 0 else i.lower() for idx, i in enumerate(letters))
Your i is a string of one character, not an index. So you can't do i%2. Use enumerate to get both the index and the value.
alternating = ''.join(letter.upper() if index%2==0 else letter.lower() for index, letter in enumerate(text)
Yes, it error, cause i now is letter not a number, so it can't mod for 2.
Im not sure syntax about looping by for in Python but may you can try:
cnt = 0
for i in letters:
if cnt%2 == 0:
return i.upper()
else:
return i.lower()
cnt++
Hope it can help you!
Fix me if I have any wrong. Thanks
#Abhi, this is inline with your original logic. You need r to get the index of the letters in the string.
def mycode(letters):
for ch in letters:
r=letters.index(ch)
if r%2 == 0:
letters=letters.replace(ch,letters[r].upper())
else:
letters=letters.replace(ch,letters[r].lower())
return letters
print(mycode('ahdjeryu'))

Letter Count on a string

Python newb here. I m trying to count the number of letter "a"s in a given string. Code is below. It keeps returning 1 instead 3 in string "banana". Any input appreciated.
def count_letters(word, char):
count = 0
while count <= len(word):
for char in word:
if char == word[count]:
count += 1
return count
print count_letters('banana','a')
The other answers show what's wrong with your code. But there's also a built-in way to do this, if you weren't just doing this for an exercise:
>>> 'banana'.count('a')
3
Danben gave this corrected version:
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
Here are some other ways to do it, hopefully they will teach you more about Python!
Similar, but shorter for loop. Exploits the fact that booleans can turn into 1 if true and 0 if false:
def count_letters(word, char):
count = 0
for c in word:
count += (char == c)
return count
Short for loops can generally be turned into list/generator comprehensions. This creates a list of integers corresponding to each letter, with 0 if the letter doesn't match char and 1 if it does, and then sums them:
def count_letters(word, char):
return sum(char == c for c in word)
The next one filters out all the characters that don't match char, and counts how many are left:
def count_letters(word, char):
return len([c for c in word if c == char])
One problem is that you are using count to refer both to the position in the word that you are checking, and the number of char you have seen, and you are using char to refer both to the input character you are checking, and the current character in the string. Use separate variables instead.
Also, move the return statement outside the loop; otherwise you will always return after checking the first character.
Finally, you only need one loop to iterate over the string. Get rid of the outer while loop and you will not need to track the position in the string.
Taking these suggestions, your code would look like this:
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
A simple way is as follows:
def count_letters(word, char):
return word.count(char)
Or, there's another way count each element directly:
from collections import Counter
Counter('banana')
Of course, you can specify one element, e.g.
Counter('banana')['a']
Your return is in your for loop! Be careful with indentation, you want the line return count to be outside the loop. Because the for loop goes through all characters in word, the outer while loop is completely unneeded.
A cleaned-up version:
def count_letters(word, to_find):
count = 0
for char in word:
if char == to_find:
count += 1
return count
You have a number of problems:
There's a problem with your indentation as others already pointed out.
There's no need to have nested loops. Just one loop is enough.
You're using char to mean two different things, but the char variable in the for loop will overwrite the data from the parameter.
This code fixes all these errors:
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
A much more concise way to write this is to use a generator expression:
def count_letters(word, char):
return sum(char == c for c in word)
Or just use the built-in method count that does this for you:
print 'abcbac'.count('c')
I see a few things wrong.
You reuse the identifier char, so that will cause issues.
You're saying if char == word[count] instead of word[some index]
You return after the first iteration of the for loop!
You don't even need the while. If you rename the char param to search,
for char in word:
if char == search:
count += 1
return count
Alternatively You can use:
mystring = 'banana'
number = mystring.count('a')
count_letters=""
number=count_letters.count("")
print number
"banana".count("ana") returns 1 instead of 2 !
I think the method iterates over the string (or the list) with a step equal to the length of the substring so it doesn't see this kind of stuff.
So if you want a "full count" you have to implement your own counter with the correct loop of step 1
Correct me if I'm wrong...
def count_letter(word, char):
count = 0
for char in word:
if char == word:
count += 1
return count #Your return is inside your for loop
r = count_word("banana", "a")
print r
3
x=str(input("insert string"))
c=0
for i in x:
if 'a' in i:
c=c+1
print(c)
Following program takes a string as input and output a pandas DataFrame, which represents the letter count.
Sample Input
hello
Sample Output
 char Freq.
0 h  1
1 e  1
2 l  2
3 o  1
import pandas as pd
def count_letters(word, char):
return word.count(char)
text = input()
text_split = text.split()
list1 = []
list2 = []
for i in text_split:
for j in i:
counter = count_letters (text, j)
list1.append(j)
list2.append(counter)
dictn = dict(zip(list1, list2))
df = pd.DataFrame (dictn.items(), columns = ['char', 'freq.'])
print (df)

Categories

Resources