I'd like feedback on my solution to the outlined (medium level) programming challenge. What might be a more efficient or Pythonic solution?
The challenge as outlined by Coderbyte:
[Run Length] (https://www.coderbyte.com/solution/Run%20Length?tblang=german)
Have the function RunLength(str) take the str parameter being passed and return a compressed version of the string using the Run-length encoding algorithm. This algorithm works by taking the occurrence of each repeating character and outputting that number along with a single character of the repeating sequence. For example: "wwwggopp" would return 3w2g1o2p. The string will not contain any numbers, punctuation, or symbols.
import doctest
import logging
import timeit
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s - %(levelname)s - %(message)s")
# logging.disable(logging.CRITICAL)
def compress_string(s: str) -> str:
"""
Indicate the freq of each char in s, removing repeated, consecutive chars
E.g. "aaabbc" outputs '3a2b1c'
:param s: the string to compress
:type s: str
:return: s as a compressed string
:rtype: str
>>> compress_string(s="wwwggopp")
'3w2g1o2p'
>>> compress_string(s="aaa")
'3a'
>>> compress_string(s="")
''
>>> compress_string(s="b")
'1b'
>>> compress_string(s="abcd")
'1a1b1c1d'
"""
if s == "":
return ""
# indexes of change in characters
indexes = [i+1 for i in range(len(s) - 1) if s[i+1] != s[i]]
# add start and end index for slicing of s
indexes.insert(0, 0)
indexes.append(len(s))
# slice string
slices = [s[indexes[i]:indexes[i+1]] for i in range(len(indexes)-1)]
compressed_str = "".join(f"{len(s)}{s[0]}" for s in slices)
return compressed_str
if __name__ == "__main__":
print(timeit.timeit("compress_string(s='wwwggoppg')",
setup="from __main__ import compress_string",
number=100000))
doctest.testmod()
aAabcaa
? \$\endgroup\$