String compression function in python code












3














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









New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1




    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").
    – Graipher
    2 hours ago


















3














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









New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1




    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").
    – Graipher
    2 hours ago
















3












3








3







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









New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











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









New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 3 hours ago









Mathias Ettinger

23.6k33182




23.6k33182






New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 3 hours ago









instaggyinstaggy

184




184




New contributor




instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






instaggy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1




    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").
    – Graipher
    2 hours ago
















  • 1




    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").
    – Graipher
    2 hours ago










1




1




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").
– Graipher
2 hours ago






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").
– Graipher
2 hours ago












4 Answers
4






active

oldest

votes


















-1














You can try to debug yourself and come up with many solutions.A way out of many I can tell you is below:



res = ""
count = 0
while (len(x) > 0):
count = 1
res= ""
for j in range(1, len(x)):
if x[0]==x[j]:
count= count + 1
else:
res = res + x[j]
print(x[0], count, end=" ")
x=res





share|improve this answer








New contributor




Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.










  • 3




    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.
    – Mathias Ettinger
    2 hours ago



















5














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























  • 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.
    – Graipher
    2 hours ago






  • 1




    @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
    – Mathias Ettinger
    2 hours ago






  • 2




    @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
    – Mathias Ettinger
    2 hours ago






  • 1




    The more I look at it, the code of the OP does not solve the stated problem at all...
    – Graipher
    2 hours ago










  • Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
    – Graipher
    2 hours ago



















1














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































    0














    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








    New contributor




    pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.


















    • Thanks, something wrong with my code?
      – instaggy
      3 hours ago










    • Not really, just suggested you a better way to perform the same per your question.
      – pycoder223
      3 hours ago










    • Many thanks, this works fine as well.
      – instaggy
      3 hours ago






    • 3




      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.
      – Mathias Ettinger
      2 hours ago











    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    instaggy is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211094%2fstring-compression-function-in-python-code%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    -1














    You can try to debug yourself and come up with many solutions.A way out of many I can tell you is below:



    res = ""
    count = 0
    while (len(x) > 0):
    count = 1
    res= ""
    for j in range(1, len(x)):
    if x[0]==x[j]:
    count= count + 1
    else:
    res = res + x[j]
    print(x[0], count, end=" ")
    x=res





    share|improve this answer








    New contributor




    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.








    We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.










    • 3




      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.
      – Mathias Ettinger
      2 hours ago
















    -1














    You can try to debug yourself and come up with many solutions.A way out of many I can tell you is below:



    res = ""
    count = 0
    while (len(x) > 0):
    count = 1
    res= ""
    for j in range(1, len(x)):
    if x[0]==x[j]:
    count= count + 1
    else:
    res = res + x[j]
    print(x[0], count, end=" ")
    x=res





    share|improve this answer








    New contributor




    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.








    We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.










    • 3




      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.
      – Mathias Ettinger
      2 hours ago














    -1












    -1








    -1






    You can try to debug yourself and come up with many solutions.A way out of many I can tell you is below:



    res = ""
    count = 0
    while (len(x) > 0):
    count = 1
    res= ""
    for j in range(1, len(x)):
    if x[0]==x[j]:
    count= count + 1
    else:
    res = res + x[j]
    print(x[0], count, end=" ")
    x=res





    share|improve this answer








    New contributor




    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    You can try to debug yourself and come up with many solutions.A way out of many I can tell you is below:



    res = ""
    count = 0
    while (len(x) > 0):
    count = 1
    res= ""
    for j in range(1, len(x)):
    if x[0]==x[j]:
    count= count + 1
    else:
    res = res + x[j]
    print(x[0], count, end=" ")
    x=res






    share|improve this answer








    New contributor




    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    share|improve this answer



    share|improve this answer






    New contributor




    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    answered 2 hours ago









    Alex56Alex56

    142




    142




    New contributor




    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





    New contributor





    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    Alex56 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.



    We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.




    We are looking for answers that provide insightful observations about the code in the question. Answers that consist of independent solutions with no justification do not constitute a code review, and may be removed.









    • 3




      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.
      – Mathias Ettinger
      2 hours ago














    • 3




      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.
      – Mathias Ettinger
      2 hours ago








    3




    3




    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.
    – Mathias Ettinger
    2 hours ago




    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.
    – Mathias Ettinger
    2 hours ago













    5














    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























    • 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.
      – Graipher
      2 hours ago






    • 1




      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      – Mathias Ettinger
      2 hours ago






    • 2




      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      – Mathias Ettinger
      2 hours ago






    • 1




      The more I look at it, the code of the OP does not solve the stated problem at all...
      – Graipher
      2 hours ago










    • Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      – Graipher
      2 hours ago
















    5














    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























    • 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.
      – Graipher
      2 hours ago






    • 1




      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      – Mathias Ettinger
      2 hours ago






    • 2




      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      – Mathias Ettinger
      2 hours ago






    • 1




      The more I look at it, the code of the OP does not solve the stated problem at all...
      – Graipher
      2 hours ago










    • Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      – Graipher
      2 hours ago














    5












    5








    5






    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














    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 2 hours ago

























    answered 2 hours ago









    Mathias EttingerMathias Ettinger

    23.6k33182




    23.6k33182












    • 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.
      – Graipher
      2 hours ago






    • 1




      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      – Mathias Ettinger
      2 hours ago






    • 2




      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      – Mathias Ettinger
      2 hours ago






    • 1




      The more I look at it, the code of the OP does not solve the stated problem at all...
      – Graipher
      2 hours ago










    • Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      – Graipher
      2 hours ago


















    • 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.
      – Graipher
      2 hours ago






    • 1




      @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
      – Mathias Ettinger
      2 hours ago






    • 2




      @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
      – Mathias Ettinger
      2 hours ago






    • 1




      The more I look at it, the code of the OP does not solve the stated problem at all...
      – Graipher
      2 hours ago










    • Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
      – Graipher
      2 hours ago
















    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.
    – Graipher
    2 hours ago




    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.
    – Graipher
    2 hours ago




    1




    1




    @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
    – Mathias Ettinger
    2 hours ago




    @Graipher For 'f' -> 'f1' I chose to keep the original behaviour
    – Mathias Ettinger
    2 hours ago




    2




    2




    @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
    – Mathias Ettinger
    2 hours ago




    @Graipher But something like letter + str(length := len(list(group))) if length > 1 else '' could work in upcomming Python 3.8
    – Mathias Ettinger
    2 hours ago




    1




    1




    The more I look at it, the code of the OP does not solve the stated problem at all...
    – Graipher
    2 hours ago




    The more I look at it, the code of the OP does not solve the stated problem at all...
    – Graipher
    2 hours ago












    Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
    – Graipher
    2 hours ago




    Yeah, I was thinking along those lines as well. But I only have 3.6 installed :)
    – Graipher
    2 hours ago











    1














    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




























      1














      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


























        1












        1








        1






        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














        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 2 hours ago

























        answered 2 hours ago









        GraipherGraipher

        23.7k53585




        23.7k53585























            0














            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








            New contributor




            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.


















            • Thanks, something wrong with my code?
              – instaggy
              3 hours ago










            • Not really, just suggested you a better way to perform the same per your question.
              – pycoder223
              3 hours ago










            • Many thanks, this works fine as well.
              – instaggy
              3 hours ago






            • 3




              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.
              – Mathias Ettinger
              2 hours ago
















            0














            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








            New contributor




            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.


















            • Thanks, something wrong with my code?
              – instaggy
              3 hours ago










            • Not really, just suggested you a better way to perform the same per your question.
              – pycoder223
              3 hours ago










            • Many thanks, this works fine as well.
              – instaggy
              3 hours ago






            • 3




              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.
              – Mathias Ettinger
              2 hours ago














            0












            0








            0






            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








            New contributor




            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            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








            New contributor




            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            share|improve this answer



            share|improve this answer






            New contributor




            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            answered 3 hours ago









            pycoder223pycoder223

            84




            84




            New contributor




            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





            New contributor





            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            pycoder223 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.












            • Thanks, something wrong with my code?
              – instaggy
              3 hours ago










            • Not really, just suggested you a better way to perform the same per your question.
              – pycoder223
              3 hours ago










            • Many thanks, this works fine as well.
              – instaggy
              3 hours ago






            • 3




              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.
              – Mathias Ettinger
              2 hours ago


















            • Thanks, something wrong with my code?
              – instaggy
              3 hours ago










            • Not really, just suggested you a better way to perform the same per your question.
              – pycoder223
              3 hours ago










            • Many thanks, this works fine as well.
              – instaggy
              3 hours ago






            • 3




              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.
              – Mathias Ettinger
              2 hours ago
















            Thanks, something wrong with my code?
            – instaggy
            3 hours ago




            Thanks, something wrong with my code?
            – instaggy
            3 hours ago












            Not really, just suggested you a better way to perform the same per your question.
            – pycoder223
            3 hours ago




            Not really, just suggested you a better way to perform the same per your question.
            – pycoder223
            3 hours ago












            Many thanks, this works fine as well.
            – instaggy
            3 hours ago




            Many thanks, this works fine as well.
            – instaggy
            3 hours ago




            3




            3




            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.
            – Mathias Ettinger
            2 hours ago




            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.
            – Mathias Ettinger
            2 hours ago










            instaggy is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            instaggy is a new contributor. Be nice, and check out our Code of Conduct.













            instaggy is a new contributor. Be nice, and check out our Code of Conduct.












            instaggy is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211094%2fstring-compression-function-in-python-code%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Contact image not getting when fetch all contact list from iPhone by CNContact

            count number of partitions of a set with n elements into k subsets

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks