Python Strings: 20 Best Questions with
Answers
Practice set (easy to advanced) — clean, exam-ready Python solutions.
Q1. Reverse a string (without slicing [::-1])
def reverse_string(s: str) -> str:
rev = ""
for ch in s:
rev = ch + rev
return rev
# Example:
# print(reverse_string("hello")) # olleh
Q2. Palindrome check
def is_palindrome(s: str) -> bool:
# Keep only letters/digits and ignore case
s2 = "".join([Link]() for ch in s if [Link]())
return s2 == s2[::-1]
# Example:
# print(is_palindrome("Madam")) # True
Q3. Count vowels and consonants
def count_vowels_consonants(s: str):
vowels = set("aeiouAEIOU")
v = c = 0
for ch in s:
if [Link]():
if ch in vowels:
v += 1
else:
c += 1
return v, c
# Example:
# print(count_vowels_consonants("Hello World")) # (3, 7)
Q4. Count frequency of each character
def char_frequency(s: str) -> dict:
freq = {}
for ch in s:
freq[ch] = [Link](ch, 0) + 1
return freq
# Example:
# print(char_frequency("banana")) # {'b':1,'a':3,'n':2}
Q5. First non-repeating character
def first_non_repeating(s: str):
freq = {}
for ch in s:
freq[ch] = [Link](ch, 0) + 1
for ch in s:
if freq[ch] == 1:
return ch
return None
# Example:
# print(first_non_repeating("aabbcdd")) # c
Q6. Remove duplicate characters (keep order)
def remove_duplicates_keep_order(s: str) -> str:
seen = set()
out = []
for ch in s:
if ch not in seen:
[Link](ch)
[Link](ch)
return "".join(out)
# Example:
# print(remove_duplicates_keep_order("banana")) # ban
Q7. Anagram check
def are_anagrams(a: str, b: str) -> bool:
a2 = "".join([Link]() for ch in a if [Link]())
b2 = "".join([Link]() for ch in b if [Link]())
return sorted(a2) == sorted(b2)
# Example:
# print(are_anagrams("listen", "silent")) # True
Q8. Most frequent character
def most_frequent_char(s: str):
if not s:
return None
freq = {}
for ch in s:
freq[ch] = [Link](ch, 0) + 1
# max by count
return max([Link](), key=lambda x: x[1]) # (char, count)
# Example:
# print(most_frequent_char("mississippi")) # ('i', 4) or ('s', 4)
Q9. Count words + word frequency
def word_count_and_frequency(sentence: str):
words = [Link]()
freq = {}
for w in words:
freq[w] = [Link](w, 0) + 1
return len(words), freq
# Example:
# print(word_count_and_frequency("hi hi joy")) # (3, {'hi':2,'joy':1})
Q10. Reverse each word in a sentence
def reverse_each_word(sentence: str) -> str:
return " ".join(word[::-1] for word in [Link]())
# Example:
# print(reverse_each_word("hi joy")) # ih yoj
Q11. Capitalize first letter of every word (without .title())
def title_case_without_title(s: str) -> str:
words = [Link]()
out = []
for w in words:
if w:
[Link](w[0].upper() + w[1:].lower())
return " ".join(out)
# Example:
# print(title_case_without_title("hELLo woRLD")) # Hello World
Q12. Remove spaces (and extra spaces)
def remove_spaces(s: str) -> str:
return "".join(ch for ch in s if ch != " ")
def remove_extra_spaces(s: str) -> str:
return " ".join([Link]())
# Example:
# print(remove_spaces("a b c")) # "ab c"? -> "abc"
# print(remove_extra_spaces("a b c")) # "a b c"
Q13. Replace all vowels with '*'
def replace_vowels(s: str) -> str:
vowels = set("aeiouAEIOU")
return "".join("*" if ch in vowels else ch for ch in s)
# Example:
# print(replace_vowels("Hello")) # H*ll*
Q14. Check only digits / only alphabets / alphanumeric
def check_string_types(s: str):
return {
"only_digits": [Link](),
"only_alpha": [Link](),
"alphanumeric": [Link](),
}
# Example:
# print(check_string_types("123")) # digits True
# print(check_string_types("abc")) # alpha True
# print(check_string_types("a1b2")) # alnum True
Q15. Find all occurrences of a substring (indexes)
def find_all_occurrences(s: str, sub: str):
if sub == "":
return []
idxs = []
start = 0
while True:
i = [Link](sub, start)
if i == -1:
break
[Link](i)
start = i + 1 # allow overlaps
return idxs
# Example:
# print(find_all_occurrences("aaaa", "aa")) # [0,1,2]
Q16. Longest word in a sentence
def longest_word(sentence: str):
words = [Link]()
if not words:
return None
return max(words, key=len)
# Example:
# print(longest_word("I love programming a lot")) # programming
Q17. Compress a string (Run-Length Encoding)
def rle_compress(s: str) -> str:
if not s:
return ""
out = []
count = 1
for i in range(1, len(s)):
if s[i] == s[i-1]:
count += 1
else:
[Link](s[i-1] + str(count))
count = 1
[Link](s[-1] + str(count))
return "".join(out)
# Example:
# print(rle_compress("aaabbc")) # a3b2c1
Q18. Expand a compressed string
def rle_expand(s: str) -> str:
# Works for patterns like a3b12c1 (multi-digit counts)
out = []
i = 0
while i < len(s):
ch = s[i]
i += 1
num = []
while i < len(s) and s[i].isdigit():
[Link](s[i])
i += 1
count = int("".join(num)) if num else 1
[Link](ch * count)
return "".join(out)
# Example:
# print(rle_expand("a3b2c1")) # aaabbc
Q19. Remove punctuation
import string
def remove_punctuation(s: str) -> str:
return "".join(ch for ch in s if ch not in [Link])
# Example:
# print(remove_punctuation("Hi, Joy!")) # Hi Joy
Q20. Longest substring without repeating characters (advanced)
def longest_unique_substring(s: str):
# Sliding window
last = {}
left = 0
best_len = 0
best_start = 0
for right, ch in enumerate(s):
if ch in last and last[ch] >= left:
left = last[ch] + 1
last[ch] = right
if right - left + 1 > best_len:
best_len = right - left + 1
best_start = left
return best_len, s[best_start:best_start + best_len]
# Example:
# print(longest_unique_substring("abcabcbb")) # (3, 'abc')