Variable table width with .format












0















I'm trying to display data from a csv in a text table. I've got to the point where it displays everything that I need, however the table width still has to be set, meaning if the data is longer than the number set then issues begin.



I currently print the table using .format to sort out formatting, is there a way to set the width of the data to a variable that is dependant on the length of the longest piece of data?



for i in range(len(list_l)):
if i == 0:
print(h_dashes)
print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', (list_l[i][0].upper()),'|', (list_l[i][1].upper()),'|',(list_l[i][2].upper()),'|', (list_l[i][3].upper()),'|'))
print(h_dashes)
else:
print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', list_l[i][0], '|', list_l[i][1], '|', list_l[i][2],'|', list_l[i][3],'|'))


I realise that the code is far from perfect, however I'm still a newbie so it's piecemeal from various tutorials










share|improve this question





























    0















    I'm trying to display data from a csv in a text table. I've got to the point where it displays everything that I need, however the table width still has to be set, meaning if the data is longer than the number set then issues begin.



    I currently print the table using .format to sort out formatting, is there a way to set the width of the data to a variable that is dependant on the length of the longest piece of data?



    for i in range(len(list_l)):
    if i == 0:
    print(h_dashes)
    print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', (list_l[i][0].upper()),'|', (list_l[i][1].upper()),'|',(list_l[i][2].upper()),'|', (list_l[i][3].upper()),'|'))
    print(h_dashes)
    else:
    print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', list_l[i][0], '|', list_l[i][1], '|', list_l[i][2],'|', list_l[i][3],'|'))


    I realise that the code is far from perfect, however I'm still a newbie so it's piecemeal from various tutorials










    share|improve this question



























      0












      0








      0








      I'm trying to display data from a csv in a text table. I've got to the point where it displays everything that I need, however the table width still has to be set, meaning if the data is longer than the number set then issues begin.



      I currently print the table using .format to sort out formatting, is there a way to set the width of the data to a variable that is dependant on the length of the longest piece of data?



      for i in range(len(list_l)):
      if i == 0:
      print(h_dashes)
      print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', (list_l[i][0].upper()),'|', (list_l[i][1].upper()),'|',(list_l[i][2].upper()),'|', (list_l[i][3].upper()),'|'))
      print(h_dashes)
      else:
      print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', list_l[i][0], '|', list_l[i][1], '|', list_l[i][2],'|', list_l[i][3],'|'))


      I realise that the code is far from perfect, however I'm still a newbie so it's piecemeal from various tutorials










      share|improve this question
















      I'm trying to display data from a csv in a text table. I've got to the point where it displays everything that I need, however the table width still has to be set, meaning if the data is longer than the number set then issues begin.



      I currently print the table using .format to sort out formatting, is there a way to set the width of the data to a variable that is dependant on the length of the longest piece of data?



      for i in range(len(list_l)):
      if i == 0:
      print(h_dashes)
      print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', (list_l[i][0].upper()),'|', (list_l[i][1].upper()),'|',(list_l[i][2].upper()),'|', (list_l[i][3].upper()),'|'))
      print(h_dashes)
      else:
      print('{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}{:^26s}{:^1s}'.format('|', list_l[i][0], '|', list_l[i][1], '|', list_l[i][2],'|', list_l[i][3],'|'))


      I realise that the code is far from perfect, however I'm still a newbie so it's piecemeal from various tutorials







      python string-formatting






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 '18 at 0:41









      aydow

      2,36011026




      2,36011026










      asked Nov 21 '18 at 0:38









      JamesPOMJamesPOM

      11




      11
























          1 Answer
          1






          active

          oldest

          votes


















          0














          You can actually use a two-pass approach to first get the correct lengths. As per your example with four fields per line, the following shows the basic idea you can use.



          What follows is an example of the two-pass approach, first to get the maximum lengths for each field, the other to do what you're currently doing (with the calculated rather than fixed lengths):



          # Can set MINIMUM lengths here if desired, eg: lengths = [10, 0, 41, 7]

          lengths = [0] * 4
          fmtstr = None

          for pass in range(2):
          for i in range(len(list_l)):
          if pass == 0:
          # First pass sets lengths as per data.

          for field in range(4):
          lengths[field] = max(lengths[field], len(list_l[i][field])
          else:
          # Second pass prints the data.

          # First, set format string if not yet set.

          if fmtstr is None:
          fmtstr = '|'
          for item in lengths:
          fmtstr += '{:^%ds}|' % (item)

          # Now print item (and header stuff if first item).

          if i == 0: print(h_dashes)
          print(fmtstr.format(list_l[i][0].upper(), list_l[i][1].upper(), list_l[i][2].upper(), list_l[i][3].upper()))
          if i == 0: print(h_dashes)




          The construction of the format string is done the first time you process an item in pass two.



          It does so by taking a collection like [31,41,59] and giving you the string:



          |{:^31s}|{:^41s}|{:^59s}|


          There's little point using all those {:^1s} format specifiers when the | is not actually a varying item - you may as well code it directly into the format string.






          share|improve this answer

























            Your Answer






            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: "1"
            };
            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: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            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
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403716%2fvariable-table-width-with-format%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            You can actually use a two-pass approach to first get the correct lengths. As per your example with four fields per line, the following shows the basic idea you can use.



            What follows is an example of the two-pass approach, first to get the maximum lengths for each field, the other to do what you're currently doing (with the calculated rather than fixed lengths):



            # Can set MINIMUM lengths here if desired, eg: lengths = [10, 0, 41, 7]

            lengths = [0] * 4
            fmtstr = None

            for pass in range(2):
            for i in range(len(list_l)):
            if pass == 0:
            # First pass sets lengths as per data.

            for field in range(4):
            lengths[field] = max(lengths[field], len(list_l[i][field])
            else:
            # Second pass prints the data.

            # First, set format string if not yet set.

            if fmtstr is None:
            fmtstr = '|'
            for item in lengths:
            fmtstr += '{:^%ds}|' % (item)

            # Now print item (and header stuff if first item).

            if i == 0: print(h_dashes)
            print(fmtstr.format(list_l[i][0].upper(), list_l[i][1].upper(), list_l[i][2].upper(), list_l[i][3].upper()))
            if i == 0: print(h_dashes)




            The construction of the format string is done the first time you process an item in pass two.



            It does so by taking a collection like [31,41,59] and giving you the string:



            |{:^31s}|{:^41s}|{:^59s}|


            There's little point using all those {:^1s} format specifiers when the | is not actually a varying item - you may as well code it directly into the format string.






            share|improve this answer






























              0














              You can actually use a two-pass approach to first get the correct lengths. As per your example with four fields per line, the following shows the basic idea you can use.



              What follows is an example of the two-pass approach, first to get the maximum lengths for each field, the other to do what you're currently doing (with the calculated rather than fixed lengths):



              # Can set MINIMUM lengths here if desired, eg: lengths = [10, 0, 41, 7]

              lengths = [0] * 4
              fmtstr = None

              for pass in range(2):
              for i in range(len(list_l)):
              if pass == 0:
              # First pass sets lengths as per data.

              for field in range(4):
              lengths[field] = max(lengths[field], len(list_l[i][field])
              else:
              # Second pass prints the data.

              # First, set format string if not yet set.

              if fmtstr is None:
              fmtstr = '|'
              for item in lengths:
              fmtstr += '{:^%ds}|' % (item)

              # Now print item (and header stuff if first item).

              if i == 0: print(h_dashes)
              print(fmtstr.format(list_l[i][0].upper(), list_l[i][1].upper(), list_l[i][2].upper(), list_l[i][3].upper()))
              if i == 0: print(h_dashes)




              The construction of the format string is done the first time you process an item in pass two.



              It does so by taking a collection like [31,41,59] and giving you the string:



              |{:^31s}|{:^41s}|{:^59s}|


              There's little point using all those {:^1s} format specifiers when the | is not actually a varying item - you may as well code it directly into the format string.






              share|improve this answer




























                0












                0








                0







                You can actually use a two-pass approach to first get the correct lengths. As per your example with four fields per line, the following shows the basic idea you can use.



                What follows is an example of the two-pass approach, first to get the maximum lengths for each field, the other to do what you're currently doing (with the calculated rather than fixed lengths):



                # Can set MINIMUM lengths here if desired, eg: lengths = [10, 0, 41, 7]

                lengths = [0] * 4
                fmtstr = None

                for pass in range(2):
                for i in range(len(list_l)):
                if pass == 0:
                # First pass sets lengths as per data.

                for field in range(4):
                lengths[field] = max(lengths[field], len(list_l[i][field])
                else:
                # Second pass prints the data.

                # First, set format string if not yet set.

                if fmtstr is None:
                fmtstr = '|'
                for item in lengths:
                fmtstr += '{:^%ds}|' % (item)

                # Now print item (and header stuff if first item).

                if i == 0: print(h_dashes)
                print(fmtstr.format(list_l[i][0].upper(), list_l[i][1].upper(), list_l[i][2].upper(), list_l[i][3].upper()))
                if i == 0: print(h_dashes)




                The construction of the format string is done the first time you process an item in pass two.



                It does so by taking a collection like [31,41,59] and giving you the string:



                |{:^31s}|{:^41s}|{:^59s}|


                There's little point using all those {:^1s} format specifiers when the | is not actually a varying item - you may as well code it directly into the format string.






                share|improve this answer















                You can actually use a two-pass approach to first get the correct lengths. As per your example with four fields per line, the following shows the basic idea you can use.



                What follows is an example of the two-pass approach, first to get the maximum lengths for each field, the other to do what you're currently doing (with the calculated rather than fixed lengths):



                # Can set MINIMUM lengths here if desired, eg: lengths = [10, 0, 41, 7]

                lengths = [0] * 4
                fmtstr = None

                for pass in range(2):
                for i in range(len(list_l)):
                if pass == 0:
                # First pass sets lengths as per data.

                for field in range(4):
                lengths[field] = max(lengths[field], len(list_l[i][field])
                else:
                # Second pass prints the data.

                # First, set format string if not yet set.

                if fmtstr is None:
                fmtstr = '|'
                for item in lengths:
                fmtstr += '{:^%ds}|' % (item)

                # Now print item (and header stuff if first item).

                if i == 0: print(h_dashes)
                print(fmtstr.format(list_l[i][0].upper(), list_l[i][1].upper(), list_l[i][2].upper(), list_l[i][3].upper()))
                if i == 0: print(h_dashes)




                The construction of the format string is done the first time you process an item in pass two.



                It does so by taking a collection like [31,41,59] and giving you the string:



                |{:^31s}|{:^41s}|{:^59s}|


                There's little point using all those {:^1s} format specifiers when the | is not actually a varying item - you may as well code it directly into the format string.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 21 '18 at 2:31

























                answered Nov 21 '18 at 1:01









                paxdiablopaxdiablo

                633k17012471670




                633k17012471670






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • 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%2fstackoverflow.com%2fquestions%2f53403716%2fvariable-table-width-with-format%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

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$