Convert boolean list to list of base10 integers

The name of the pictureThe name of the pictureThe name of the pictureClash 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?










share|improve this question









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.























    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?










    share|improve this question









    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.





















      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?










      share|improve this question









      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






      share|improve this question









      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.











      share|improve this question









      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.









      share|improve this question




      share|improve this question








      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.




















          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.






          share|improve this answer




















          • 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










          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',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );






          Ari Cooper-Davis 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%2f205532%2fconvert-boolean-list-to-list-of-base10-integers%23new-answer', 'question_page');

          );

          Post as a guest






























          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.






          share|improve this answer




















          • 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














          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.






          share|improve this answer




















          • 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












          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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
















          • 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










          Ari Cooper-Davis is a new contributor. Be nice, and check out our Code of Conduct.









           

          draft saved


          draft discarded


















          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.













           


          draft saved


          draft discarded














          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













































































          Comments

          Popular posts from this blog

          What does second last employer means? [closed]

          List of Gilmore Girls characters

          Confectionery