Convert boolean list to list of base10 integers
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I need help making my list comprehension a little more pythonic! I'm working with long strings of binary data and need to extract integers from it, as follows.
Problem:
Take a boolean list of known length...
l = [1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1]
...split it into 8-bit sublists...
[[1, 0, 1, 0, 0, 1, 1, 1], [0, 0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 1, 0, 1, 1]]
...concatenate each sublist into a string...
[10100111, 101010, 111011]
...convert those strings from binary to decimal...
[167, 42, 59]
...then scale those integers between 50 and 150...
[115, 66, 73]
My solution:
[int(int(str(bin), 2)/2.55)+50 for bin in [int(''.join(
map(str,num))) for num in [l[i:i +8] for i in range(0, len(l), 8)]]]
This feels like a very ugly way to go tackle the problem - can anyone come up with a nicer way to go about it?
python performance strings
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |Â
up vote
2
down vote
favorite
I need help making my list comprehension a little more pythonic! I'm working with long strings of binary data and need to extract integers from it, as follows.
Problem:
Take a boolean list of known length...
l = [1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1]
...split it into 8-bit sublists...
[[1, 0, 1, 0, 0, 1, 1, 1], [0, 0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 1, 0, 1, 1]]
...concatenate each sublist into a string...
[10100111, 101010, 111011]
...convert those strings from binary to decimal...
[167, 42, 59]
...then scale those integers between 50 and 150...
[115, 66, 73]
My solution:
[int(int(str(bin), 2)/2.55)+50 for bin in [int(''.join(
map(str,num))) for num in [l[i:i +8] for i in range(0, len(l), 8)]]]
This feels like a very ugly way to go tackle the problem - can anyone come up with a nicer way to go about it?
python performance strings
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I need help making my list comprehension a little more pythonic! I'm working with long strings of binary data and need to extract integers from it, as follows.
Problem:
Take a boolean list of known length...
l = [1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1]
...split it into 8-bit sublists...
[[1, 0, 1, 0, 0, 1, 1, 1], [0, 0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 1, 0, 1, 1]]
...concatenate each sublist into a string...
[10100111, 101010, 111011]
...convert those strings from binary to decimal...
[167, 42, 59]
...then scale those integers between 50 and 150...
[115, 66, 73]
My solution:
[int(int(str(bin), 2)/2.55)+50 for bin in [int(''.join(
map(str,num))) for num in [l[i:i +8] for i in range(0, len(l), 8)]]]
This feels like a very ugly way to go tackle the problem - can anyone come up with a nicer way to go about it?
python performance strings
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I need help making my list comprehension a little more pythonic! I'm working with long strings of binary data and need to extract integers from it, as follows.
Problem:
Take a boolean list of known length...
l = [1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1]
...split it into 8-bit sublists...
[[1, 0, 1, 0, 0, 1, 1, 1], [0, 0, 1, 0, 1, 0, 1, 0], [0, 0, 1, 1, 1, 0, 1, 1]]
...concatenate each sublist into a string...
[10100111, 101010, 111011]
...convert those strings from binary to decimal...
[167, 42, 59]
...then scale those integers between 50 and 150...
[115, 66, 73]
My solution:
[int(int(str(bin), 2)/2.55)+50 for bin in [int(''.join(
map(str,num))) for num in [l[i:i +8] for i in range(0, len(l), 8)]]]
This feels like a very ugly way to go tackle the problem - can anyone come up with a nicer way to go about it?
python performance strings
python performance strings
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 3 hours ago
New contributor
Ari Cooper-Davis 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


Ari Cooper-Davis
1165
1165
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Ari Cooper-Davis is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
The individual steps that you describe in the Problem section are each simple and easy to follow. Yet you write your code in basically a single line. To understand it I had to tear it apart like you did in your "explanation for humans":
scaled = [
int(int(str(bin), 2)/2.55)+50
for bin in [
int(''.join(map(str, num)))
for num in [
l[i : i+8] for i in
range(0, len(l), 8)]]]
I have also reformatted the code to better see the underlying structure. Together with your explanation, this works for understanding it.
But since you chose to not include the explanation within your code, I would have no chance to understand it by reading it alone.
Therefore, I find it easier to understand when you name the intermediate steps:
chunks = [l[i : i+8] for i in range(0, len(l), 8)]
binaries = [int(''.join(map(str, chunk))) for chunk in chunks]
numbers = [int(str(binary), 2) for binary in binaries]
scaled = [round(50 + (150 - 50) * number / (255 - 0)) for number in numbers]
The aim of PEP8 is to ensure readable code. Having too many different ideas in a single line of code does not count as readable to me. Therefore I prefer the form with the intermediate steps.
Sure, the broken down version of the code is longer, but the reader of your code can take a deep breath after each step and inspect the intermediate result, just as you did in your explanation. Therefore the code should look this way.
By the way, I replaced the very last int
with round
since I think it is more appropriate. Decide for yourself. I also replaced the magic number 2.55 with the numbers from your explanation. This makes the numbers less magic.
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
The individual steps that you describe in the Problem section are each simple and easy to follow. Yet you write your code in basically a single line. To understand it I had to tear it apart like you did in your "explanation for humans":
scaled = [
int(int(str(bin), 2)/2.55)+50
for bin in [
int(''.join(map(str, num)))
for num in [
l[i : i+8] for i in
range(0, len(l), 8)]]]
I have also reformatted the code to better see the underlying structure. Together with your explanation, this works for understanding it.
But since you chose to not include the explanation within your code, I would have no chance to understand it by reading it alone.
Therefore, I find it easier to understand when you name the intermediate steps:
chunks = [l[i : i+8] for i in range(0, len(l), 8)]
binaries = [int(''.join(map(str, chunk))) for chunk in chunks]
numbers = [int(str(binary), 2) for binary in binaries]
scaled = [round(50 + (150 - 50) * number / (255 - 0)) for number in numbers]
The aim of PEP8 is to ensure readable code. Having too many different ideas in a single line of code does not count as readable to me. Therefore I prefer the form with the intermediate steps.
Sure, the broken down version of the code is longer, but the reader of your code can take a deep breath after each step and inspect the intermediate result, just as you did in your explanation. Therefore the code should look this way.
By the way, I replaced the very last int
with round
since I think it is more appropriate. Decide for yourself. I also replaced the magic number 2.55 with the numbers from your explanation. This makes the numbers less magic.
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
add a comment |Â
up vote
2
down vote
accepted
The individual steps that you describe in the Problem section are each simple and easy to follow. Yet you write your code in basically a single line. To understand it I had to tear it apart like you did in your "explanation for humans":
scaled = [
int(int(str(bin), 2)/2.55)+50
for bin in [
int(''.join(map(str, num)))
for num in [
l[i : i+8] for i in
range(0, len(l), 8)]]]
I have also reformatted the code to better see the underlying structure. Together with your explanation, this works for understanding it.
But since you chose to not include the explanation within your code, I would have no chance to understand it by reading it alone.
Therefore, I find it easier to understand when you name the intermediate steps:
chunks = [l[i : i+8] for i in range(0, len(l), 8)]
binaries = [int(''.join(map(str, chunk))) for chunk in chunks]
numbers = [int(str(binary), 2) for binary in binaries]
scaled = [round(50 + (150 - 50) * number / (255 - 0)) for number in numbers]
The aim of PEP8 is to ensure readable code. Having too many different ideas in a single line of code does not count as readable to me. Therefore I prefer the form with the intermediate steps.
Sure, the broken down version of the code is longer, but the reader of your code can take a deep breath after each step and inspect the intermediate result, just as you did in your explanation. Therefore the code should look this way.
By the way, I replaced the very last int
with round
since I think it is more appropriate. Decide for yourself. I also replaced the magic number 2.55 with the numbers from your explanation. This makes the numbers less magic.
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
The individual steps that you describe in the Problem section are each simple and easy to follow. Yet you write your code in basically a single line. To understand it I had to tear it apart like you did in your "explanation for humans":
scaled = [
int(int(str(bin), 2)/2.55)+50
for bin in [
int(''.join(map(str, num)))
for num in [
l[i : i+8] for i in
range(0, len(l), 8)]]]
I have also reformatted the code to better see the underlying structure. Together with your explanation, this works for understanding it.
But since you chose to not include the explanation within your code, I would have no chance to understand it by reading it alone.
Therefore, I find it easier to understand when you name the intermediate steps:
chunks = [l[i : i+8] for i in range(0, len(l), 8)]
binaries = [int(''.join(map(str, chunk))) for chunk in chunks]
numbers = [int(str(binary), 2) for binary in binaries]
scaled = [round(50 + (150 - 50) * number / (255 - 0)) for number in numbers]
The aim of PEP8 is to ensure readable code. Having too many different ideas in a single line of code does not count as readable to me. Therefore I prefer the form with the intermediate steps.
Sure, the broken down version of the code is longer, but the reader of your code can take a deep breath after each step and inspect the intermediate result, just as you did in your explanation. Therefore the code should look this way.
By the way, I replaced the very last int
with round
since I think it is more appropriate. Decide for yourself. I also replaced the magic number 2.55 with the numbers from your explanation. This makes the numbers less magic.
The individual steps that you describe in the Problem section are each simple and easy to follow. Yet you write your code in basically a single line. To understand it I had to tear it apart like you did in your "explanation for humans":
scaled = [
int(int(str(bin), 2)/2.55)+50
for bin in [
int(''.join(map(str, num)))
for num in [
l[i : i+8] for i in
range(0, len(l), 8)]]]
I have also reformatted the code to better see the underlying structure. Together with your explanation, this works for understanding it.
But since you chose to not include the explanation within your code, I would have no chance to understand it by reading it alone.
Therefore, I find it easier to understand when you name the intermediate steps:
chunks = [l[i : i+8] for i in range(0, len(l), 8)]
binaries = [int(''.join(map(str, chunk))) for chunk in chunks]
numbers = [int(str(binary), 2) for binary in binaries]
scaled = [round(50 + (150 - 50) * number / (255 - 0)) for number in numbers]
The aim of PEP8 is to ensure readable code. Having too many different ideas in a single line of code does not count as readable to me. Therefore I prefer the form with the intermediate steps.
Sure, the broken down version of the code is longer, but the reader of your code can take a deep breath after each step and inspect the intermediate result, just as you did in your explanation. Therefore the code should look this way.
By the way, I replaced the very last int
with round
since I think it is more appropriate. Decide for yourself. I also replaced the magic number 2.55 with the numbers from your explanation. This makes the numbers less magic.
answered 1 hour ago
Roland Illig
10.5k11743
10.5k11743
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
add a comment |Â
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
Many thanks Roland, this is exactly what I needed to hear. I find it so easy to get caught up in reducing code down to simplify it that I make it less simple than it would have been to start with! Excellent suggestion replacing 'int' with 'round', and by making it more obvious where that number came from.
– Ari Cooper-Davis
12 mins ago
add a comment |Â
Ari Cooper-Davis is a new contributor. Be nice, and check out our Code of Conduct.
Ari Cooper-Davis is a new contributor. Be nice, and check out our Code of Conduct.
Ari Cooper-Davis is a new contributor. Be nice, and check out our Code of Conduct.
Ari Cooper-Davis is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f205532%2fconvert-boolean-list-to-list-of-base10-integers%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password