String compression function in python code [closed]












3












$begingroup$


I need to create a function called compress that compresses a string by replacing any repeated letters with a letter and number. Can someone suggest a better way to do this?



s=input("Enter the string:")
temp={}
result=" "
for x in s:
if x in temp:
temp[x]=temp[x]+1
else:
temp[x]=1
for key,value in temp.items():
result+=str(key)+str(value)
print(result)









share|improve this question











$endgroup$



closed as off-topic by Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld Jan 8 at 21:07


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld

If this question can be reworded to fit the rules in the help center, please edit the question.












  • 4




    $begingroup$
    Your code does not seem to actually solve the problem you stated. The order of letters is not preserved and if a letter only occures once you add a 1 instead of just outputting it ("aba" -> "a2b1" instead of "aba" -> "aba").
    $endgroup$
    – Graipher
    Jan 8 at 13:25








  • 2




    $begingroup$
    In addition to the problem Graipher reported, there is also unexepected indentation on the last line...
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jan 8 at 18:24
















3












$begingroup$


I need to create a function called compress that compresses a string by replacing any repeated letters with a letter and number. Can someone suggest a better way to do this?



s=input("Enter the string:")
temp={}
result=" "
for x in s:
if x in temp:
temp[x]=temp[x]+1
else:
temp[x]=1
for key,value in temp.items():
result+=str(key)+str(value)
print(result)









share|improve this question











$endgroup$



closed as off-topic by Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld Jan 8 at 21:07


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld

If this question can be reworded to fit the rules in the help center, please edit the question.












  • 4




    $begingroup$
    Your code does not seem to actually solve the problem you stated. The order of letters is not preserved and if a letter only occures once you add a 1 instead of just outputting it ("aba" -> "a2b1" instead of "aba" -> "aba").
    $endgroup$
    – Graipher
    Jan 8 at 13:25








  • 2




    $begingroup$
    In addition to the problem Graipher reported, there is also unexepected indentation on the last line...
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jan 8 at 18:24














3












3








3





$begingroup$


I need to create a function called compress that compresses a string by replacing any repeated letters with a letter and number. Can someone suggest a better way to do this?



s=input("Enter the string:")
temp={}
result=" "
for x in s:
if x in temp:
temp[x]=temp[x]+1
else:
temp[x]=1
for key,value in temp.items():
result+=str(key)+str(value)
print(result)









share|improve this question











$endgroup$




I need to create a function called compress that compresses a string by replacing any repeated letters with a letter and number. Can someone suggest a better way to do this?



s=input("Enter the string:")
temp={}
result=" "
for x in s:
if x in temp:
temp[x]=temp[x]+1
else:
temp[x]=1
for key,value in temp.items():
result+=str(key)+str(value)
print(result)






python python-3.x python-2.x






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 8 at 12:58









Mathias Ettinger

25.1k33285




25.1k33285










asked Jan 8 at 12:33









instaggyinstaggy

245




245




closed as off-topic by Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld Jan 8 at 21:07


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld

If this question can be reworded to fit the rules in the help center, please edit the question.







closed as off-topic by Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld Jan 8 at 21:07


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Code not implemented or not working as intended: Code Review is a community where programmers peer-review your working code to address issues such as security, maintainability, performance, and scalability. We require that the code be working correctly, to the best of the author's knowledge, before proceeding with a review." – Graipher, Donald.McLean, Sᴀᴍ Onᴇᴌᴀ, IEatBagels, AJNeufeld

If this question can be reworded to fit the rules in the help center, please edit the question.








  • 4




    $begingroup$
    Your code does not seem to actually solve the problem you stated. The order of letters is not preserved and if a letter only occures once you add a 1 instead of just outputting it ("aba" -> "a2b1" instead of "aba" -> "aba").
    $endgroup$
    – Graipher
    Jan 8 at 13:25








  • 2




    $begingroup$
    In addition to the problem Graipher reported, there is also unexepected indentation on the last line...
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jan 8 at 18:24














  • 4




    $begingroup$
    Your code does not seem to actually solve the problem you stated. The order of letters is not preserved and if a letter only occures once you add a 1 instead of just outputting it ("aba" -> "a2b1" instead of "aba" -> "aba").
    $endgroup$
    – Graipher
    Jan 8 at 13:25








  • 2




    $begingroup$
    In addition to the problem Graipher reported, there is also unexepected indentation on the last line...
    $endgroup$
    – Sᴀᴍ Onᴇᴌᴀ
    Jan 8 at 18:24








4




4




$begingroup$
Your code does not seem to actually solve the problem you stated. The order of letters is not preserved and if a letter only occures once you add a 1 instead of just outputting it ("aba" -> "a2b1" instead of "aba" -> "aba").
$endgroup$
– Graipher
Jan 8 at 13:25






$begingroup$
Your code does not seem to actually solve the problem you stated. The order of letters is not preserved and if a letter only occures once you add a 1 instead of just outputting it ("aba" -> "a2b1" instead of "aba" -> "aba").
$endgroup$
– Graipher
Jan 8 at 13:25






2




2




$begingroup$
In addition to the problem Graipher reported, there is also unexepected indentation on the last line...
$endgroup$
– Sᴀᴍ Onᴇᴌᴀ
Jan 8 at 18:24




$begingroup$
In addition to the problem Graipher reported, there is also unexepected indentation on the last line...
$endgroup$
– Sᴀᴍ Onᴇᴌᴀ
Jan 8 at 18:24










3 Answers
3






active

oldest

votes


















9












$begingroup$

Encapsulate your code into functions



Your code is neither reusable nor testable, wrap it into a function and call it from under an if __name__ == '__main__' guard. This will allow you to test it more easily. You will also be able to return values instead of printing them, this will make the code more reusable:



def compress(string):
temp={}
result=" "
for x in string:
if x in temp:
temp[x] = temp[x]+1
else:
temp[x] = 1
for key, value in temp.items():
result += str(key) + str(value)

return result


if __name__ == '__main__':
s = input("Enter the string:")
print(compress(s))


You can then jump into an interactive shell and type:



>>> from your_file_name import compress
>>> compress('aaabbccccddefg')
a3b2c4d2e1f1g1
>>> compress('b'*42)
b42


Use existing data structures



collections.Counter offers simplified ways of counting elements of an iterable:



from collections import Counter


def compress(string):
temp = Counter()
result = " "
for x in string:
temp[x] += 1

for key, value in temp.items():
result += str(key) + str(value)
return result


if __name__ == '__main__':
s = input("Enter the string:")
print(compress(s))


You can even simplify further as Counter can take any iterable in its constructor. You can also use str.join to simplify even further:



from collections import Counter


def compress(string):
counts = Counter(string)
return ''.join(letter+str(count) for letter, count in counts.items())


if __name__ == '__main__':
print(compress(input("Enter the string: ")))


Possible bug



To me, compressing a string mean having a mean to decompress it back. Using a dictionnary keyed by each letter as you do, you lost an important information: which letter is next to which one. Also 'aabaabaabaa' will be compressed to 'a8b3' which, to me, doesn't make sense and would be better as 'a2b1a2b1a2b1a2'. But I might be wrong. In this case, itertools.groupby is much more usefull as it will keep the ordering and avoid aggregating separate groups of letters:



import itertools


def compress(string):
return ''.join(
letter + str(len(list(group)))
for letter, group in itertools.groupby(string))


if __name__ == '__main__':
print(compress(input("Enter the string: ")))





share|improve this answer











$endgroup$













  • $begingroup$
    And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
    $endgroup$
    – Graipher
    Jan 8 at 13:21






  • 1




    $begingroup$
    @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
    $endgroup$
    – Mathias Ettinger
    Jan 8 at 13:22






  • 2




    $begingroup$
    @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
    $endgroup$
    – Mathias Ettinger
    Jan 8 at 13:23






  • 1




    $begingroup$
    The more I look at it, the code of the OP does not solve the stated problem at all...
    $endgroup$
    – Graipher
    Jan 8 at 13:24










  • $begingroup$
    Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
    $endgroup$
    – Graipher
    Jan 8 at 13:24



















2












$begingroup$

In the itertools module there is the groupby function that groups together runs of the same values.



You can use it like this here:



from itertools import groupby

def compress(s):
out =
for name, group in groupby(s):
length_of_run = len(list(group))
if length_of_run == 1:
out.append(name)
else:
out.append(f"{name}{length_of_run}")
return "".join(out)


This also uses the more modern f-strings instead of manually building the string with str calls and + and puts everything into a function that you can reuse.



It also has the advantage that it directly iterates over the input, instead of over its indices (have a look at Loop like a Native!). This makes it work also for a generator, which does not have a length:



from itertools import islice, cycle

compress(islice(cycle('a'), 10))
# 'a10'





share|improve this answer











$endgroup$





















    -2












    $begingroup$

    This could be one of the way to do it:



    count = 1
    for i in range(1, len(input) + 1):
    if i == len(input):
    print(input[i - 1] + str(count), end="")
    break
    else:
    if input[i - 1] == input[i]:
    count += 1
    else:
    print(input[i - 1] + str(count), end="")
    count = 1





    share|improve this answer









    $endgroup$













    • $begingroup$
      Thanks, something wrong with my code?
      $endgroup$
      – instaggy
      Jan 8 at 12:39










    • $begingroup$
      Not really, just suggested you a better way to perform the same per your question.
      $endgroup$
      – pycoder223
      Jan 8 at 12:40






    • 5




      $begingroup$
      You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:19


















    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    9












    $begingroup$

    Encapsulate your code into functions



    Your code is neither reusable nor testable, wrap it into a function and call it from under an if __name__ == '__main__' guard. This will allow you to test it more easily. You will also be able to return values instead of printing them, this will make the code more reusable:



    def compress(string):
    temp={}
    result=" "
    for x in string:
    if x in temp:
    temp[x] = temp[x]+1
    else:
    temp[x] = 1
    for key, value in temp.items():
    result += str(key) + str(value)

    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can then jump into an interactive shell and type:



    >>> from your_file_name import compress
    >>> compress('aaabbccccddefg')
    a3b2c4d2e1f1g1
    >>> compress('b'*42)
    b42


    Use existing data structures



    collections.Counter offers simplified ways of counting elements of an iterable:



    from collections import Counter


    def compress(string):
    temp = Counter()
    result = " "
    for x in string:
    temp[x] += 1

    for key, value in temp.items():
    result += str(key) + str(value)
    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can even simplify further as Counter can take any iterable in its constructor. You can also use str.join to simplify even further:



    from collections import Counter


    def compress(string):
    counts = Counter(string)
    return ''.join(letter+str(count) for letter, count in counts.items())


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))


    Possible bug



    To me, compressing a string mean having a mean to decompress it back. Using a dictionnary keyed by each letter as you do, you lost an important information: which letter is next to which one. Also 'aabaabaabaa' will be compressed to 'a8b3' which, to me, doesn't make sense and would be better as 'a2b1a2b1a2b1a2'. But I might be wrong. In this case, itertools.groupby is much more usefull as it will keep the ordering and avoid aggregating separate groups of letters:



    import itertools


    def compress(string):
    return ''.join(
    letter + str(len(list(group)))
    for letter, group in itertools.groupby(string))


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))





    share|improve this answer











    $endgroup$













    • $begingroup$
      And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
      $endgroup$
      – Graipher
      Jan 8 at 13:21






    • 1




      $begingroup$
      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:22






    • 2




      $begingroup$
      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:23






    • 1




      $begingroup$
      The more I look at it, the code of the OP does not solve the stated problem at all...
      $endgroup$
      – Graipher
      Jan 8 at 13:24










    • $begingroup$
      Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      $endgroup$
      – Graipher
      Jan 8 at 13:24
















    9












    $begingroup$

    Encapsulate your code into functions



    Your code is neither reusable nor testable, wrap it into a function and call it from under an if __name__ == '__main__' guard. This will allow you to test it more easily. You will also be able to return values instead of printing them, this will make the code more reusable:



    def compress(string):
    temp={}
    result=" "
    for x in string:
    if x in temp:
    temp[x] = temp[x]+1
    else:
    temp[x] = 1
    for key, value in temp.items():
    result += str(key) + str(value)

    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can then jump into an interactive shell and type:



    >>> from your_file_name import compress
    >>> compress('aaabbccccddefg')
    a3b2c4d2e1f1g1
    >>> compress('b'*42)
    b42


    Use existing data structures



    collections.Counter offers simplified ways of counting elements of an iterable:



    from collections import Counter


    def compress(string):
    temp = Counter()
    result = " "
    for x in string:
    temp[x] += 1

    for key, value in temp.items():
    result += str(key) + str(value)
    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can even simplify further as Counter can take any iterable in its constructor. You can also use str.join to simplify even further:



    from collections import Counter


    def compress(string):
    counts = Counter(string)
    return ''.join(letter+str(count) for letter, count in counts.items())


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))


    Possible bug



    To me, compressing a string mean having a mean to decompress it back. Using a dictionnary keyed by each letter as you do, you lost an important information: which letter is next to which one. Also 'aabaabaabaa' will be compressed to 'a8b3' which, to me, doesn't make sense and would be better as 'a2b1a2b1a2b1a2'. But I might be wrong. In this case, itertools.groupby is much more usefull as it will keep the ordering and avoid aggregating separate groups of letters:



    import itertools


    def compress(string):
    return ''.join(
    letter + str(len(list(group)))
    for letter, group in itertools.groupby(string))


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))





    share|improve this answer











    $endgroup$













    • $begingroup$
      And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
      $endgroup$
      – Graipher
      Jan 8 at 13:21






    • 1




      $begingroup$
      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:22






    • 2




      $begingroup$
      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:23






    • 1




      $begingroup$
      The more I look at it, the code of the OP does not solve the stated problem at all...
      $endgroup$
      – Graipher
      Jan 8 at 13:24










    • $begingroup$
      Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      $endgroup$
      – Graipher
      Jan 8 at 13:24














    9












    9








    9





    $begingroup$

    Encapsulate your code into functions



    Your code is neither reusable nor testable, wrap it into a function and call it from under an if __name__ == '__main__' guard. This will allow you to test it more easily. You will also be able to return values instead of printing them, this will make the code more reusable:



    def compress(string):
    temp={}
    result=" "
    for x in string:
    if x in temp:
    temp[x] = temp[x]+1
    else:
    temp[x] = 1
    for key, value in temp.items():
    result += str(key) + str(value)

    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can then jump into an interactive shell and type:



    >>> from your_file_name import compress
    >>> compress('aaabbccccddefg')
    a3b2c4d2e1f1g1
    >>> compress('b'*42)
    b42


    Use existing data structures



    collections.Counter offers simplified ways of counting elements of an iterable:



    from collections import Counter


    def compress(string):
    temp = Counter()
    result = " "
    for x in string:
    temp[x] += 1

    for key, value in temp.items():
    result += str(key) + str(value)
    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can even simplify further as Counter can take any iterable in its constructor. You can also use str.join to simplify even further:



    from collections import Counter


    def compress(string):
    counts = Counter(string)
    return ''.join(letter+str(count) for letter, count in counts.items())


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))


    Possible bug



    To me, compressing a string mean having a mean to decompress it back. Using a dictionnary keyed by each letter as you do, you lost an important information: which letter is next to which one. Also 'aabaabaabaa' will be compressed to 'a8b3' which, to me, doesn't make sense and would be better as 'a2b1a2b1a2b1a2'. But I might be wrong. In this case, itertools.groupby is much more usefull as it will keep the ordering and avoid aggregating separate groups of letters:



    import itertools


    def compress(string):
    return ''.join(
    letter + str(len(list(group)))
    for letter, group in itertools.groupby(string))


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))





    share|improve this answer











    $endgroup$



    Encapsulate your code into functions



    Your code is neither reusable nor testable, wrap it into a function and call it from under an if __name__ == '__main__' guard. This will allow you to test it more easily. You will also be able to return values instead of printing them, this will make the code more reusable:



    def compress(string):
    temp={}
    result=" "
    for x in string:
    if x in temp:
    temp[x] = temp[x]+1
    else:
    temp[x] = 1
    for key, value in temp.items():
    result += str(key) + str(value)

    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can then jump into an interactive shell and type:



    >>> from your_file_name import compress
    >>> compress('aaabbccccddefg')
    a3b2c4d2e1f1g1
    >>> compress('b'*42)
    b42


    Use existing data structures



    collections.Counter offers simplified ways of counting elements of an iterable:



    from collections import Counter


    def compress(string):
    temp = Counter()
    result = " "
    for x in string:
    temp[x] += 1

    for key, value in temp.items():
    result += str(key) + str(value)
    return result


    if __name__ == '__main__':
    s = input("Enter the string:")
    print(compress(s))


    You can even simplify further as Counter can take any iterable in its constructor. You can also use str.join to simplify even further:



    from collections import Counter


    def compress(string):
    counts = Counter(string)
    return ''.join(letter+str(count) for letter, count in counts.items())


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))


    Possible bug



    To me, compressing a string mean having a mean to decompress it back. Using a dictionnary keyed by each letter as you do, you lost an important information: which letter is next to which one. Also 'aabaabaabaa' will be compressed to 'a8b3' which, to me, doesn't make sense and would be better as 'a2b1a2b1a2b1a2'. But I might be wrong. In this case, itertools.groupby is much more usefull as it will keep the ordering and avoid aggregating separate groups of letters:



    import itertools


    def compress(string):
    return ''.join(
    letter + str(len(list(group)))
    for letter, group in itertools.groupby(string))


    if __name__ == '__main__':
    print(compress(input("Enter the string: ")))






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 8 at 13:21

























    answered Jan 8 at 13:18









    Mathias EttingerMathias Ettinger

    25.1k33285




    25.1k33285












    • $begingroup$
      And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
      $endgroup$
      – Graipher
      Jan 8 at 13:21






    • 1




      $begingroup$
      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:22






    • 2




      $begingroup$
      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:23






    • 1




      $begingroup$
      The more I look at it, the code of the OP does not solve the stated problem at all...
      $endgroup$
      – Graipher
      Jan 8 at 13:24










    • $begingroup$
      Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      $endgroup$
      – Graipher
      Jan 8 at 13:24


















    • $begingroup$
      And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
      $endgroup$
      – Graipher
      Jan 8 at 13:21






    • 1




      $begingroup$
      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:22






    • 2




      $begingroup$
      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      $endgroup$
      – Mathias Ettinger
      Jan 8 at 13:23






    • 1




      $begingroup$
      The more I look at it, the code of the OP does not solve the stated problem at all...
      $endgroup$
      – Graipher
      Jan 8 at 13:24










    • $begingroup$
      Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      $endgroup$
      – Graipher
      Jan 8 at 13:24
















    $begingroup$
    And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
    $endgroup$
    – Graipher
    Jan 8 at 13:21




    $begingroup$
    And then encoding 'f' as 'f1' is the opposite of compressing. But if you find a nice way to write it as a comprehension that would be nice, I could not think of any.
    $endgroup$
    – Graipher
    Jan 8 at 13:21




    1




    1




    $begingroup$
    @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
    $endgroup$
    – Mathias Ettinger
    Jan 8 at 13:22




    $begingroup$
    @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
    $endgroup$
    – Mathias Ettinger
    Jan 8 at 13:22




    2




    2




    $begingroup$
    @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
    $endgroup$
    – Mathias Ettinger
    Jan 8 at 13:23




    $begingroup$
    @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
    $endgroup$
    – Mathias Ettinger
    Jan 8 at 13:23




    1




    1




    $begingroup$
    The more I look at it, the code of the OP does not solve the stated problem at all...
    $endgroup$
    – Graipher
    Jan 8 at 13:24




    $begingroup$
    The more I look at it, the code of the OP does not solve the stated problem at all...
    $endgroup$
    – Graipher
    Jan 8 at 13:24












    $begingroup$
    Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
    $endgroup$
    – Graipher
    Jan 8 at 13:24




    $begingroup$
    Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
    $endgroup$
    – Graipher
    Jan 8 at 13:24













    2












    $begingroup$

    In the itertools module there is the groupby function that groups together runs of the same values.



    You can use it like this here:



    from itertools import groupby

    def compress(s):
    out =
    for name, group in groupby(s):
    length_of_run = len(list(group))
    if length_of_run == 1:
    out.append(name)
    else:
    out.append(f"{name}{length_of_run}")
    return "".join(out)


    This also uses the more modern f-strings instead of manually building the string with str calls and + and puts everything into a function that you can reuse.



    It also has the advantage that it directly iterates over the input, instead of over its indices (have a look at Loop like a Native!). This makes it work also for a generator, which does not have a length:



    from itertools import islice, cycle

    compress(islice(cycle('a'), 10))
    # 'a10'





    share|improve this answer











    $endgroup$


















      2












      $begingroup$

      In the itertools module there is the groupby function that groups together runs of the same values.



      You can use it like this here:



      from itertools import groupby

      def compress(s):
      out =
      for name, group in groupby(s):
      length_of_run = len(list(group))
      if length_of_run == 1:
      out.append(name)
      else:
      out.append(f"{name}{length_of_run}")
      return "".join(out)


      This also uses the more modern f-strings instead of manually building the string with str calls and + and puts everything into a function that you can reuse.



      It also has the advantage that it directly iterates over the input, instead of over its indices (have a look at Loop like a Native!). This makes it work also for a generator, which does not have a length:



      from itertools import islice, cycle

      compress(islice(cycle('a'), 10))
      # 'a10'





      share|improve this answer











      $endgroup$
















        2












        2








        2





        $begingroup$

        In the itertools module there is the groupby function that groups together runs of the same values.



        You can use it like this here:



        from itertools import groupby

        def compress(s):
        out =
        for name, group in groupby(s):
        length_of_run = len(list(group))
        if length_of_run == 1:
        out.append(name)
        else:
        out.append(f"{name}{length_of_run}")
        return "".join(out)


        This also uses the more modern f-strings instead of manually building the string with str calls and + and puts everything into a function that you can reuse.



        It also has the advantage that it directly iterates over the input, instead of over its indices (have a look at Loop like a Native!). This makes it work also for a generator, which does not have a length:



        from itertools import islice, cycle

        compress(islice(cycle('a'), 10))
        # 'a10'





        share|improve this answer











        $endgroup$



        In the itertools module there is the groupby function that groups together runs of the same values.



        You can use it like this here:



        from itertools import groupby

        def compress(s):
        out =
        for name, group in groupby(s):
        length_of_run = len(list(group))
        if length_of_run == 1:
        out.append(name)
        else:
        out.append(f"{name}{length_of_run}")
        return "".join(out)


        This also uses the more modern f-strings instead of manually building the string with str calls and + and puts everything into a function that you can reuse.



        It also has the advantage that it directly iterates over the input, instead of over its indices (have a look at Loop like a Native!). This makes it work also for a generator, which does not have a length:



        from itertools import islice, cycle

        compress(islice(cycle('a'), 10))
        # 'a10'






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 8 at 13:14

























        answered Jan 8 at 13:08









        GraipherGraipher

        26.6k54092




        26.6k54092























            -2












            $begingroup$

            This could be one of the way to do it:



            count = 1
            for i in range(1, len(input) + 1):
            if i == len(input):
            print(input[i - 1] + str(count), end="")
            break
            else:
            if input[i - 1] == input[i]:
            count += 1
            else:
            print(input[i - 1] + str(count), end="")
            count = 1





            share|improve this answer









            $endgroup$













            • $begingroup$
              Thanks, something wrong with my code?
              $endgroup$
              – instaggy
              Jan 8 at 12:39










            • $begingroup$
              Not really, just suggested you a better way to perform the same per your question.
              $endgroup$
              – pycoder223
              Jan 8 at 12:40






            • 5




              $begingroup$
              You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
              $endgroup$
              – Mathias Ettinger
              Jan 8 at 13:19
















            -2












            $begingroup$

            This could be one of the way to do it:



            count = 1
            for i in range(1, len(input) + 1):
            if i == len(input):
            print(input[i - 1] + str(count), end="")
            break
            else:
            if input[i - 1] == input[i]:
            count += 1
            else:
            print(input[i - 1] + str(count), end="")
            count = 1





            share|improve this answer









            $endgroup$













            • $begingroup$
              Thanks, something wrong with my code?
              $endgroup$
              – instaggy
              Jan 8 at 12:39










            • $begingroup$
              Not really, just suggested you a better way to perform the same per your question.
              $endgroup$
              – pycoder223
              Jan 8 at 12:40






            • 5




              $begingroup$
              You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
              $endgroup$
              – Mathias Ettinger
              Jan 8 at 13:19














            -2












            -2








            -2





            $begingroup$

            This could be one of the way to do it:



            count = 1
            for i in range(1, len(input) + 1):
            if i == len(input):
            print(input[i - 1] + str(count), end="")
            break
            else:
            if input[i - 1] == input[i]:
            count += 1
            else:
            print(input[i - 1] + str(count), end="")
            count = 1





            share|improve this answer









            $endgroup$



            This could be one of the way to do it:



            count = 1
            for i in range(1, len(input) + 1):
            if i == len(input):
            print(input[i - 1] + str(count), end="")
            break
            else:
            if input[i - 1] == input[i]:
            count += 1
            else:
            print(input[i - 1] + str(count), end="")
            count = 1






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 8 at 12:37









            pycoder223pycoder223

            14




            14












            • $begingroup$
              Thanks, something wrong with my code?
              $endgroup$
              – instaggy
              Jan 8 at 12:39










            • $begingroup$
              Not really, just suggested you a better way to perform the same per your question.
              $endgroup$
              – pycoder223
              Jan 8 at 12:40






            • 5




              $begingroup$
              You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
              $endgroup$
              – Mathias Ettinger
              Jan 8 at 13:19


















            • $begingroup$
              Thanks, something wrong with my code?
              $endgroup$
              – instaggy
              Jan 8 at 12:39










            • $begingroup$
              Not really, just suggested you a better way to perform the same per your question.
              $endgroup$
              – pycoder223
              Jan 8 at 12:40






            • 5




              $begingroup$
              You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
              $endgroup$
              – Mathias Ettinger
              Jan 8 at 13:19
















            $begingroup$
            Thanks, something wrong with my code?
            $endgroup$
            – instaggy
            Jan 8 at 12:39




            $begingroup$
            Thanks, something wrong with my code?
            $endgroup$
            – instaggy
            Jan 8 at 12:39












            $begingroup$
            Not really, just suggested you a better way to perform the same per your question.
            $endgroup$
            – pycoder223
            Jan 8 at 12:40




            $begingroup$
            Not really, just suggested you a better way to perform the same per your question.
            $endgroup$
            – pycoder223
            Jan 8 at 12:40




            5




            5




            $begingroup$
            You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
            $endgroup$
            – Mathias Ettinger
            Jan 8 at 13:19




            $begingroup$
            You have presented an alternative solution, but haven't reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) so that the author and other readers can learn from your thought process.
            $endgroup$
            – Mathias Ettinger
            Jan 8 at 13:19



            Popular posts from this blog

            Bressuire

            Cabo Verde

            Gyllenstierna