Code to output the first repeated character in given string? - python

I'm trying to find the first repeated character in my string and output that character using python. When checking my code, I can see I'm not index the last character of my code.
What am I doing wrong?
letters = 'acbdc'
for a in range (0,len(letters)-1):
#print(letters[a])
for b in range(0, len(letters)-1):
#print(letters[b])
if (letters[a]==letters[b]) and (a!=b):
print(b)
b=b+1
a=a+1

You can do this in an easier way:
letters = 'acbdc'
found_dict = {}
for i in letters:
if i in found_dict:
print(i)
break
else:
found_dict[i]= 1
Output:
c

Here's a solution with sets, it should be slightly faster than using dicts.
letters = 'acbdc'
seen = set()
for letter in letters:
if letter in seen:
print(letter)
break
else:
seen.add(letter)

Here is a solution that would stop iteration as soon as it finds a dup
>>> from itertools import dropwhile
>>> s=set(); next(dropwhile(lambda c: not (c in s or s.add(c)), letters))
'c'

You should use range(0, len(letters)) instead of range(0, len(letters) - 1) because range already stops counting at one less than the designated stop value. Subtracting 1 from the stop value simply makes you skip the last character of letters in this case.
Please read the documentation of range:
https://docs.python.org/3/library/stdtypes.html#range

There were a few issues with your code...
1.Remove -1 from len(letters)
2.Move back one indent and do b = b + 1 even if you don't go into the if statement
3.Indent and do a = a + 1 in the first for loop.
See below of how to fix your code...
letters = 'acbdc'
for a in range(0, len(letters)):
# print(letters[a])
for b in range(0, len(letters)):
# print(letters[b])
if (letters[a] == letters[b]) and (a != b):
print(b)
b = b + 1
a = a + 1

Nice one-liner generator:
l = 'acbdc'
next(e for e in l if l.count(e)>1)
Or following the rules in the comments to fit the "abba" case:
l = 'acbdc'
next(e for c,e in enumerate(l) if l[:c+1].count(e)>1)

If complexity is not an issue then this will work fine.
letters = 'acbdc'
found = False
for i in range(0, len(letters)-1):
for j in range(i+1, len(letters)):
if (letters[i] == letters[j]):
print (letters[j])
found = True
break
if (found):
break

The below code prints the first repeated character in a string. I used the functionality of the list to solve this problem.
def findChar(inputString):
list = []
for c in inputString:
if c in list:
return c
else:
list.append(c)
return 'None'
print (findChar('gotgogle'))
Working fine as well. It gives the result as 'g'.

def first_repeated_char(str1):
for index,c in enumerate(str1):
if str1[:index+1].count(c) > 1:
return c
return "None"
print(first_repeated_char("abcdabcd"))

str_24 = input("Enter the string:")
for i in range(0,len(str_24)):
first_repeated_count = str_24.count(str_24[i])
if(first_repeated_count > 1):
break
print("First repeated char is:{} and character is
{}".format(first_repeated_count,str_24[i]))

Related

Print all the "a" of a string on python

I'm trying to print all the "a" or other characters from an input string. I'm trying it with the .find() function but just print one position of the characters. How do I print all the positions where is an specific character like "a"
You can use find with while loop
a = "aabababaa"
k = 0
while True:
k = a.find("a", k) # This is saying to start from where you left
if k == -1:
break
k += 1
print(k)
This is also possible with much less amount of code if you don't care where you want to start.
a = "aabababaa"
for i, c in enumerate(a): # i = Index, c = Character. Using the Enumerate()
if ("a" in c):
print(i)
Some first-get-all-matches-and-then-print versions:
With a list comprehension:
s = "aslkbasaaa"
CHAR = "a"
pos = [i for i, char in enumerate(s) if char == CHAR]
print(*pos, sep='\n')
or with itertools and composition of functions
from itertools import compress
s = "aslkbasaaa"
CHAR = "a"
pos = compress(range(len(s)), map(CHAR.__eq__, s))
print(*pos, sep='\n')

Loop to find space with python

c = "ab cd ef gf"
n = []
for x in c:
if x == " ":
d = c.find(x)
n.append(d)
print(n)
I want this code to give me something like this. [2,5,8]
But instead it is giving me this. [2,2,2]
Please help me find the mistake. Thank you.
find() will find the first instance, so it always finds the space at index 2. You could keep track of the index as you go with enumerate() so you don't need find():
c = "ab cd ef gf"
n = []
for i, x in enumerate(c):
if x == " ":
n.append(i)
print(n)
Alternatively as a list comprehension:
[i for i, x in enumerate(c) if x == " "]
One way to do it would be:
space_idxs = []
for idx, char in enumerate(s):
if char == ' ':
space_idxs.append(idx)
That's because find(pattern) function returns the first entry of the pattern. Let me supplement your code with required function find_all(string, pattern)
def find_all(string, pattern):
start = 0
indexes = []
for char in string:
start = string.find(pattern, start)
if start == -1:
return indexes
indexes.append(start)
start += len(pattern)
c = "ab cd ef gf"
n = []
n = find_all(c, " ")
print(n)
try
c="ab cd ef gh"
x=" "
print([t for t, k in enumerate(c) if k==x])
it will return [2,5,8]
in your code you are searching for the index value of x in c, three times:
in the for loop you are taking all the characters in your string one by one,
the if loop validates if it is a space
now when the character is a space it enters the if loop
the find command will look for x (space) in c
which is 2
the same is repeated three times and are appended to n
if you want it in a list:
n=([t for t, k in enumerate(c) if k==x])

Returning a list from a function that stops on the word "bye" and depending on its position

So this is the question: Write a function called beginning that takes a list as input and contains a while loop that only stops once the element of the list is the string ‘bye’. What is returned is a list that contains up to the first 10 strings, regardless of where the loop stops. (i.e., if it stops on the 32nd element, the first 10 are returned. If “bye” is the 5th element, the first 4 are returned.)
I have the part where it stops if it gets to 'bye' but i don't know how to finish the last part.
def beginning(x):
n = 0
lst = []
while "bye" not in x[n]:
lst.append(x[n])
n = n + 1
return lst
You already have a counter in your loop. Use it to add an extra condition:
def beginning(x):
n = 0
lst = []
while "bye" not in x[n] and n < 10:
lst.append(x[n])
n = n + 1
return lst
If lst reachs length 10, you do not need to check further, you already have your 10 elements, so you can stop iterating.
EDIT after comments
As pointed out in the comments, if you are looking for an exact match, this code does not work. The while loop condition instead should be:
while "bye" != x[n] and n < 10:
"bye" not in x[n] returns False if the string x[n] contains "bye", so "Goodbye" will also stop the iteration.
What should happen if "bye" is not on the list? Should it return 10 elements too? If that's the case then here:
def beginning(lis):
ls = []
counter = 1
for st in lis:
if (st != "bye") and (counter <=10):
ls.append(st)
else:
return ls
counter += 1
There is a simple solution to this problem:
def beginning(x):
ls = []
idx = 0
while idx<10:
if x[idx]=="bye":
break
ls.append(x[idx])
idx+=1
return ls
Here's my simple but lengthy solution
def beginning(lst):
ten=10
a=0
new_list=[]
while a<len(lst) and lst[a]!='bye':
new_list.append(lst[a])
a+=1
if len(new_list)>10 or len(new_list)==10:
return new_list[:10]
else:
return new_list
def beginning(list1):
sub_list = []
final_list = []
if len(list1) > 10:
sub_list = list1[:10]
count = 0
while (count<len(sub_list)) and (sub_list[count] != "bye"):
final_list.append(sub_list[count])
count = count + 1
return final_list
this way i tried , is by using the most basic functions ,if you just read once you will get it and remember the way too ! since i am a novice learner this is the only way i know !
#check_this_out!
def beginning(lst):
new_list = []
start = 0
while start < 10 and lst[start] != 'bye':
new_list.append(lst[start])
start += 1
return new_list
list1 = ["Hello", "There", "bye", "Hi", "K", "EHEH", "Edkf"]
print(beginning(list1))
You can just use the index of the first 'bye' and return the list up to that point, or up to 10, whichever is first.
def beginning(x):
return x[:min(x.index('bye'),9)]

Alternate letters in a string - code not working

I am trying to make a string alternate between upper and lower case letters. My current code is this:
def skyline (str1):
result = ''
index = 0
for i in str1:
result += str1[index].upper() + str1[index + 1].lower()
index += 2
return result
When I run the above code I get an error saying String index out of range. How can I fix this?
One way using below with join + enumerate:
s = 'asdfghjkl'
''.join(v.upper() if i%2==0 else v.lower() for i, v in enumerate(s))
#'AsDfGhJkL'
This is the way I would rewrite your logic:
from itertools import islice, zip_longest
def skyline(str1):
result = ''
index = 0
for i, j in zip_longest(str1[::2], islice(str1, 1, None, 2), fillvalue=''):
result += i.upper() + j.lower()
return result
res = skyline('hello')
'HeLlO'
Explanation
Use itertools.zip_longest to iterate chunks of your string.
Use itertools.islice to extract every second character without building a separate string.
Now just iterate through your zipped iterable and append as before.
Try for i in range(len(str1)): and substitute index for i in the code. After, you could do
if i % 2 == 0: result += str1[i].upper()
else: result += str1[i].lower()
For every character in your input string, you are incrementing the index by 2. That's why you are going out of bounds.
Try using length of string for that purpose.
you do not check if your index is still in the size of your string.
It would be necessary to add a condition which verifies if the value of i is always smaller than the string and that i% 2 == 0 and that i == 0 to put the 1st character in Upper
with i% 2 == 0 we will apply the upper one letter on two
for i, __ in enumerate(str1):
if i+1 < len(str1) and i % 2 == 0 or i == 0:
result += str1[i].upper() + str1[i + 1].lower()
I tried to modify as minimal as possible in your code, so that you could understand properly. I just added a for loop with step 2 so that you wouldn't end up with index out of range. And for the final character in case of odd length string, I handled separately.
def skyline (str1):
result = ''
length = len(str1)
for index in range(0, length - 1, 2):
result += str1[index].upper() + str1[index + 1].lower()
if length % 2 == 1:
result += str1[length - 1].upper()
return result
You can use the following code:
def myfunc(str1):
result=''
for i in range(0,len(str1)):
if i % 2 == 0:
result += str1[i].upper()
else:
result += str1[i].lower()
return result
in your code you are get 2 word by one time so you should divide your loop by 2 because your loop work by depending your input string so make an variable like peak and equal it to len(your input input) then peak = int(peak/2) it will solve your pr
def func(name):
counter1 = 0
counter2 = 1
string = ''
peak = len(name)
peak = int(peak/2)
for letter in range(1,peak+1):
string += name[counter1].lower() + name[counter2].upper()
counter1 +=2
counter2 +=2
return string

Find the next iteration in loop python

I am trying to find out if given a string if 2 target characters follow one another. So essentially, I am trying to find if a character and its neighbor are target characters. How should I go about this? The following is what I have tried so far.
target_list=["t","a","r","g","e","t"]
for char in some_string:
if (char and some_string[some_string.index(char)+1]) in target_list:
print ("correct")
else:
print ("incorrect")
Expected output:
if some_string="heytr" == "correct"
if some_string="hyt" == "incorrect"
if some_string="heyt" == "incorrect"
Just go through the indices and process every pair of characters:
for i in range(len(some_string) - 1):
if some_string[i] in target_list and some_string[i+1] in target_list:
print ("correct")
break
if i == len(some_string) - 1:
print ("incorrect")
You can alternatively create a mapping and look for adjacent true positives:
m = [(char in target_list) for char in some_string]
for i in range(len(m) - 1):
if m[i] and m[i+1]:
print ("correct")
break
if i == len(m) - 1:
print ("incorrect")
Just use map:
target_list=['t','a','r','g','e']
def toDict(list):
mp = {}
for c in list:
mp[c] = True
return mp
d = toDict(target_list)
print("dict:" , d)
def check(string, mp):
count = 0
for c in string:
if(mp.get(c,False)):
count = count+1
if(count > 1):
return True
else:
count = 0
return False
print("check:" , check("heytr", d))
print("check:" , check("hyt", d))
print("check:" , check("heyt", d))
from itertools import tee
def rolling_window(iterable, n=2):
iterators = tee(iterable, n)
for i, iterator in enumerate(iterators):
for skip in range(i):
next(iterator, None)
return zip(*iterators)
def match(some_string, target, n=2):
target = set(target)
return any(target.issuperset(s) for s in rolling_window(some_string, n=n))
A regular expression solution.
import re
target_chars='target'
p = re.compile('[%s]{2}' % re.escape(target_chars))
m = p.search(some_string)
if m:
print('correct')
else:
print('incorrect')
You can also use any() and zip() for this:
target_list=["t","a","r","g","e","t"]
target_list = set(target_list)
some_strings = ["heytr", "hyt", "heyt"]
def match_strings(string, target_list):
return any(x in target_list and y in target_list for x, y in zip(string, string[1:]))
for some_string in some_strings:
if match_strings(some_string, target_list):
print("correct")
else:
print("incorrect")
Which Outputs:
correct
incorrect
incorrect
Logic of above code:
Converts target_list to a set, since set lookup is constant time. If you keep it as a list, then lookup time is linear.
Uses zip() to create pairs of the current element and the next element, and checks if both of these elements exist in target_list. Then checks if any() of the pairs exist, which returns True if any of the pairs exist, and False if none exist.
Then loop over all the strings in some_strings, and check the above for each one.
def judge(some_string):
for index in range(0,len(some_string)-1):
if some_string[index] in target_list and some_string[index+1] in target_list:
print("correct")
break
else:
print("incorrect")
judge("heytr") --correct
judge("hyt") -- incorrect
judge("heyt") --incorrect
For loop iterates on all character of the string checks if i and i+1 is present in target.if yes prints out correct. after all iterations of loop is over if no two character are found in target it comes to the else part of for loop and prints out incorrect.

Categories