Reputation: 73
I am currently upping my Python-game and have a task, to create a function, that checks for non-repeating characters in a sequence: Below is my solution.
def find_first_non_repeated_char(sequence: str):
characters = [el for el in sequence.lower()]
my_dict = {el:characters.count(el) for el in characters if characters.count(el) == 1}
if bool(my_dict) == False or my_dict.values() == 1:
return None
else:
return list(my_dict)[0]
Upon calling this in my IDE I get it working everytime. However, the testing algo, probably used by Entwicklerheld.de seems to throw the following error:
Traceback (most recent call last):
File "/data/task-data/alphabet/tests.py", line 49, in test_random
f"Expected '{result}', but was '{find_first_non_repeated_char(random_string)}' in '{random_string}'")
AssertionError: 'a' != 'A'
- a
+ A
: Expected 'A', but was 'a' in 'A'
The letter obviously changes with every run, but the core message remains the same. What am I doing wrong? :-D I haven't seen this before ...
The task begins as follows:
Given is the sequence EntwicklerHeld. You need to find the first character that is in the given string, but is in it only once. Capital letters count equal as small letters, but you have to return the letter of the input sequence. For the string EntwicklerHeld your function should return 'n'.
Thus, when I leave out the lower()-function I cannot get the first target, because the code then evaluates to "E", but "n" should be the one!
All the best, K
Upvotes: 1
Views: 6608
Reputation: 1480
The error message is a bit mysterious, so check your instructions for input and output, but your method is also quite complicated. It would a good use of the Counter
class from collections
.
from collections import Counter
def find_first_non_repeated_char(sequence: str):
used = Counter(sequence.lower())
for el in sequence:
if used[el.lower()] == 1:
return el
return None
Upvotes: 0
Reputation: 36
my_dict
by iterating over the original sequence def find_first_non_repeated_char(sequence: str):
characters = sequence.lower()
my_dict = {el: characters.count(el.lower()) for el in sequence if characters.count(el.lower()) == 1}
if bool(my_dict) == False or my_dict.values() == 1:
return None
else:
return list(my_dict)[0]
Upvotes: 0
Reputation: 791
EDIT : The case of the characters are not taken into account for the evaluation. You can try a method like this :
seq = "EntwicklerHeld"
seq = seq.lower()
my_dict = {el:seq.count(el) for el in seq}
print([s for s in seq if my_dict[s] == 1][0])
Now back to issues with your original code :
The way you have created my_dict
is correct, but you are not using it properly. You should iterate over the original sequence of characters and return the first character present in my_dict
as the order of characters is relevant.
bool(my_dict) == False
: I do not understand this.my_dict.values() == 1
: mydict.values()
will result in a list and comparison will result as false everytime.ORIGINAL : You are changing all the characters to lower case in the line
characters = [el for el in sequence.lower()]
That seems unnecessary.
Upvotes: 1