Find a repeated character in a string (python) - string

I managed to find this code online which showed me how to find and print a repeated character in a string. I'm confused as to how it's working though. I don't understand what the h[i] = 0 part is technically doing. Can someone please explain?
a = 'abcdeab'
h = {}
for i in a:
if i in h:
print(i)
else:
h[i] = 0
I understand how it's iterating over the string, but I don't understand how it's being added to the dictionary in order to be checked if it already exists in that dictionary or not. Setting h[i] = 0 is what's throwing me off. I don't understand why it's being set to 0.
I'm adding this after the problem was answered:
I ended up creating a different solution and thought I would post it in case anyone else was looking into the same problem. It is as follows (using a list instead of a dictionary):
a = 'abcdeab'
h = []
for i in a:
if i in h:
print(i)
else:
h.append(i)
Also, if you're looking for ONLY the first occurrence of a repeated character, you would add break after print(i). In this case, it would only print a instead of both a and b.

The variable h has been defined to be a dictionary. For each letter in your input string, if it be present in the map, it gets printed, otherwise the map gets assigned a (key, value) pair of (letter, 0). That is, an entry is made into the map with the letter as the key, and zero as the (arbitrary) value. Here is your loop with some comments:
for i in a:
if i in h: # if the key 'i' exists in the dictionary
print(i)
else:
h[i] = 0 # otherwise add an entry for this letter

Related

Checking words using "YNEOS"

In this problem, I take two strings from the user, the first string being s and the second string being t. If t is the reverse of s, I print "YES" else I print "NO".
Here is my code which gives me expected outputs:
s = input()
t = input()
if t == s[::-1]:
print("YES")
else:
print("NO")
But I found another approach that I am curious to understand, but the slicing part is making me confused. Here the code goes:
print("YNEOS"[input()!=input()[::-1]::2])
Trying to find a good explanation, so StackOverflow is what came to my mind before anything else.
Let's first extract the parts of that expression that concern the input/output and the string reversal. We then get this solution:
s = input()
t = input()
trev = t[::-1]
result = "YNEOS"[s != trev::2]
print(result)
The focus of the question is on the expression "YNEOS"[s != trev::2]
Now we get to the "trick" that is performed here. The expression s != trev can be either False or True. This boolean value becomes the first part in the slicing. You'd expect to have the start index of the slice at this position. But the boolean value will also work, as booleans are a subclass of integers, and False is 0 and True is 1. So the above expression evaluates to either:
"YNEOS"[0::2]
or
"YNEOS"[1::2]
The 2 serves as the step, and so "YNEOS"[0::2] will take the characters at indices 0, 2 and 4 ("YES"), while "YNEOS"[1::2] takes the characters at indices 1 and 3 ("NO").
I hope this clarifies it.

Palindrome problem - Trying to check 2 lists for equality python3.9

I'm writing a program to check if a given user input is a palindrome or not. if it is the program should print "Yes", if not "no". I realize that this program is entirely too complex since I actually only needed to check the whole word using the reversed() function, but I ended up making it quite complex by splitting the word into two lists and then checking the lists against each other.
Despite that, I'm not clear why the last conditional isn't returning the expected "Yes" when I pass it "racecar" as an input. When I print the lists in line 23 and 24, I get two lists that are identical, but then when I compare them in the conditional, I always get "No" meaning they are not equal to each other. can anyone explain why this is? I've tried to convert the lists to strings but no luck.
def odd_or_even(a): # function for determining if odd or even
if len(a) % 2 == 0:
return True
else:
return False
the_string = input("How about a word?\n")
x = int(len(the_string))
odd_or_even(the_string) # find out if the word has an odd or an even number of characters
if odd_or_even(the_string) == True: # if even
for i in range(x):
first_half = the_string[0:int((x/2))] #create a list with part 1
second_half = the_string[(x-(int((x/2)))):x] #create a list with part 2
else: #if odd
for i in range(x):
first_half = the_string[:(int((x-1)/2))] #create a list with part 1 without the middle index
second_half = the_string[int(int(x-1)/2)+1:] #create a list with part 2 without the middle index
print(list(reversed(second_half)))
print(list(first_half))
if first_half == reversed(second_half): ##### NOT WORKING BUT DONT KNOW WHY #####
print("Yes")
else:
print("No")
Despite your comments first_half and second_half are substrings of your input, not lists. When you print them out, you're converting them to lists, but in the comparison, you do not convert first_half or reversed(second_half). Thus you are comparing a string to an iterator (returned by reversed), which will always be false.
So a basic fix is to do the conversion for the if, just like you did when printing the lists out:
if list(first_half) == list(reversed(second_half)):
A better fix might be to compare as strings, by making one of the slices use a step of -1, so you don't need to use reversed. Try second_half = the_string[-1:x//2:-1] (or similar, you probably need to tweak either the even or odd case by one). Or you could use the "alien smiley" slice to reverse the string after you slice it out of the input: second_half = second_half[::-1].
There are a few other oddities in your code, like your for i in range(x) loop that overwrites all of its results except the last one. Just use x - 1 in the slicing code and you don't need that loop at all. You're also calling int a lot more often than you need to (if you used // instead of /, you could get rid of literally all of the int calls).

comparing int value in list throws index out of range Error

I'm struggling to grasp the problem here. I already tried everything but the issue persist.
Basically I have a list of random numbers and when I try to compare the vaalues inside loop it throws "IndexError: list index out of range"
I even tried with range(len(who) and len(who) . Same thing. When put 0 instead "currentskill" which is int variable it works. What I don't understand is why comparing both values throws this Error. It just doesn't make sence...
Am I not comparing a value but the index itself ???
EDIT: I even tried with print(i) / print(who[i] to see if everything is clean and where it stops, and I'm definitelly not going outside of index
who = [2, 0, 1]
currentskill = 1
for i in who:
if who[i] == currentskill: # IndexError: list index out of range
who.pop(i)
The problem is once you start popping out elements list size varies
For eg take a list of size 6
But you iterate over all indices up to len(l)-1 = 6-1 = 5 and the index 5 does not exist in the list after removing elements in a previous iteration.
solution for this problem,
l = [x for x in l if x]
Here x is a condition you want to implement on the element of the list which you are iterating.
As stated by #Hemesh
The problem is once you start popping out elements list size varies
Problem solved. I'm just popping the element outside the loop now and it works:
def deleteskill(who, currentskill):
temp = 0
for i in range(len(who)):
if who[i] == currentskill:
temp = i
who.pop(temp)
There are two problems in your code:
mixing up the values and indexes, as pointed out by another answer; and
modifying the list while iterating over it
The solution depends on whether you want to remove just one item, or potentially multiple.
For removing just one item:
for idx, i in enumerate(who)::
if i == currentskill:
who.pop(idx)
break
For removing multiple items:
to_remove = []
for idx, i in enumerate(who)::
if i == currentskill:
to_remove.append[idx]
for idx in reversed(to_remove):
who.pop(idx)
Depending on the situation, it may be easier to create a new list instead:
who = [i for i in who if i != currentskill]
Your logic is wrong. To get the index as well as the value, use the built-in function enumerate:
idx_to_remove = []
for idx, i in enumerate(who)::
if i == currentskill:
idx_to_remove.append[idx]
for idx in reversed(idx_to_remove):
who.pop(idx)
Edited after suggestion from #sabik

Writing a function to see how many times a character appears in a set of words

To better help understand the fundamentals, my professor asked people in our class to write a function to see how many times a character appears in a set of words. I am having trouble integrating ord() into the function. Also, I understand that there are easier ways of getting the outcome.
Here is what I have so far:
def function(char):
word = "yes"
for char in word:
ord(char)
return ord(char)
function('y')
I don't get any errors - but I also don't get anything back
That is because you aren't printing anything!
Also, there are issues in your code, first one being the parameter 'char' and the 'char' in the for loop have the same name, that will cause issues.
A small code to find the count of a given letter can be something like this:
def function(word, char):
count = 0
for c in word:
if c == char:
count = count + 1
return count
print (function("yes", 'y'))
return will automatically end a function, and not keep it going.
there are also a lot of variables that you are not using, like the char parameter you passed to your function. when using the for loop, the variable created after for will be reassigned.
try this:
def function():
word = 'yes'
NewList = []
for char in word:
NewList.append(ord(char))
return NewList
print(function())
however what i think would be better:
def function(word):
NewList = []
for char in word:
NewList.append(ord(char))
return NewList
print(function('blahblah'))
also, when simply calling a function from a file, the returned value is not automatically displayed, you must include a call to print

Find characters inside strings from the elements of a list in python

I just started to use python 3. I want to find specific characters inside a string that is part of a list. Here is my code:
num = ["one","two","threex"]
for item in num:
if item.find("x"):
print("found")
So, I want to print "found" if the character "x" is inside of one of the elements of the list. But when I run the code, it prints 3 times instead of one.
Why is printing 3 times? Can someone help me?
find() returns -1 if the character is not found in the string. Anything that is not zero is equal to True. try if item.find("x") > -1.
You can use in again for strings:
num = ["one","two","threex"]
for item in num:
if "x" in item:
print("found")
Think in Strings as a list of chars like "ext" -> ['e', 'x', 't']
so "x" in "extreme" is True
find returns Index if found and -1 otherwise.
num = ["one","two","threex"]
for item in num:
if item.find("x"):
print item.find("x")
i hope that you got the solution from above post ,here you know the reason why
You need to break out of looping through the strings if 'x' is found as otherwise, it may be found in other strings. Also, when checking if 'x' is in the string, use in instead.
num = ["one","two","threex"]
for item in num:
if "x" in item:
print("found")
break
which outputs:
found
And if I modify the num list so that it has no x in any of the elements:
num = ["one","two","three"]
then there is no output when running the code again.
But why was it printing 3 times before?
Well simply, using item.find("x") will return an integer of the index of 'x' in the string. And the problem with evaluating this with an if-statement is that an integer always evaluates to True unless it is 0. This means that every string in the num list passed the test: if item.find("x") and so for each of the 3 strings, found was printed. In fact, the only time that found wouldn't be printed would be if the string began with an 'x'. In which case, the index of 'x' would be 0 and the if would evaluate to False.
Hope this clears up why your code wasn't working.
Oh, and some examples of testing the if:
>>> if 0:
... print("yes")
...
>>> if 1:
... print("yes")
...
yes
>>> if -1:
... print("yes")
...
yes

Resources