String compression function in python code [closed]
$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)
python python-3.x python-2.x
$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.
add a comment |
$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)
python python-3.x python-2.x
$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 a1
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
add a comment |
$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)
python python-3.x python-2.x
$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
python python-3.x python-2.x
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 a1
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
add a comment |
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 a1
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
add a comment |
3 Answers
3
active
oldest
votes
$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: ")))
$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 likeletter + 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
add a comment |
$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'
$endgroup$
add a comment |
$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
$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
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
$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: ")))
$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 likeletter + 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
add a comment |
$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: ")))
$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 likeletter + 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
add a comment |
$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: ")))
$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: ")))
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 likeletter + 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
add a comment |
$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 likeletter + 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
add a comment |
$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'
$endgroup$
add a comment |
$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'
$endgroup$
add a comment |
$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'
$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'
edited Jan 8 at 13:14
answered Jan 8 at 13:08
GraipherGraipher
26.6k54092
26.6k54092
add a comment |
add a comment |
$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
$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
add a comment |
$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
$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
add a comment |
$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
$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
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
add a comment |
$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
add a comment |
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