How to pythonically avoid this code duplication with a while loop?












1















I want to find the first filename myfile????.txt that doesn't exist yet (???? is a number). This works:



import os
i = 0
f = 'myfile%04i.txt' % i
while os.path.exists(f):
i += 1
f = 'myfile%04i.txt' % i


but I don't like the code duplication of f = ....



Is there a pythonic way to avoid the code duplication in this while loop?



NB: I have posted a half-satisfactory solution, using a do/while idiom, as mentioned in the main answer of Emulate a do-while loop in Python?, but I still wonder if there is better way for this particular case (thus, it's not a dupe of this question).










share|improve this question




















  • 1





    glob.glob with some regex would probably be the best way to go.

    – Ev. Kounis
    Nov 27 '18 at 14:35






  • 1





    A nice solution is coming next year: python.org/dev/peps/pep-0572

    – VPfB
    Nov 27 '18 at 15:02
















1















I want to find the first filename myfile????.txt that doesn't exist yet (???? is a number). This works:



import os
i = 0
f = 'myfile%04i.txt' % i
while os.path.exists(f):
i += 1
f = 'myfile%04i.txt' % i


but I don't like the code duplication of f = ....



Is there a pythonic way to avoid the code duplication in this while loop?



NB: I have posted a half-satisfactory solution, using a do/while idiom, as mentioned in the main answer of Emulate a do-while loop in Python?, but I still wonder if there is better way for this particular case (thus, it's not a dupe of this question).










share|improve this question




















  • 1





    glob.glob with some regex would probably be the best way to go.

    – Ev. Kounis
    Nov 27 '18 at 14:35






  • 1





    A nice solution is coming next year: python.org/dev/peps/pep-0572

    – VPfB
    Nov 27 '18 at 15:02














1












1








1


1






I want to find the first filename myfile????.txt that doesn't exist yet (???? is a number). This works:



import os
i = 0
f = 'myfile%04i.txt' % i
while os.path.exists(f):
i += 1
f = 'myfile%04i.txt' % i


but I don't like the code duplication of f = ....



Is there a pythonic way to avoid the code duplication in this while loop?



NB: I have posted a half-satisfactory solution, using a do/while idiom, as mentioned in the main answer of Emulate a do-while loop in Python?, but I still wonder if there is better way for this particular case (thus, it's not a dupe of this question).










share|improve this question
















I want to find the first filename myfile????.txt that doesn't exist yet (???? is a number). This works:



import os
i = 0
f = 'myfile%04i.txt' % i
while os.path.exists(f):
i += 1
f = 'myfile%04i.txt' % i


but I don't like the code duplication of f = ....



Is there a pythonic way to avoid the code duplication in this while loop?



NB: I have posted a half-satisfactory solution, using a do/while idiom, as mentioned in the main answer of Emulate a do-while loop in Python?, but I still wonder if there is better way for this particular case (thus, it's not a dupe of this question).







python loops while-loop code-duplication






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 27 '18 at 14:40







Basj

















asked Nov 27 '18 at 14:32









BasjBasj

6,26632107233




6,26632107233








  • 1





    glob.glob with some regex would probably be the best way to go.

    – Ev. Kounis
    Nov 27 '18 at 14:35






  • 1





    A nice solution is coming next year: python.org/dev/peps/pep-0572

    – VPfB
    Nov 27 '18 at 15:02














  • 1





    glob.glob with some regex would probably be the best way to go.

    – Ev. Kounis
    Nov 27 '18 at 14:35






  • 1





    A nice solution is coming next year: python.org/dev/peps/pep-0572

    – VPfB
    Nov 27 '18 at 15:02








1




1





glob.glob with some regex would probably be the best way to go.

– Ev. Kounis
Nov 27 '18 at 14:35





glob.glob with some regex would probably be the best way to go.

– Ev. Kounis
Nov 27 '18 at 14:35




1




1





A nice solution is coming next year: python.org/dev/peps/pep-0572

– VPfB
Nov 27 '18 at 15:02





A nice solution is coming next year: python.org/dev/peps/pep-0572

– VPfB
Nov 27 '18 at 15:02












5 Answers
5






active

oldest

votes


















6














You do not need to follow the while paradiagm here, a nested generator expression with next() works:



import os
from itertools import count
f = next(f for f in ('myfile%04i.txt' % i for i in count()) if not os.path.exists(f))
print(f)





share|improve this answer


























  • Perfect solution (I just edited so that we can easily test it by copying/pasting).

    – Basj
    Nov 27 '18 at 14:46











  • @Basj ok, note I just edited it a bit to correct a mistake (of mine)

    – Chris_Rands
    Nov 27 '18 at 14:47








  • 1





    This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

    – Basj
    Nov 27 '18 at 14:49



















3














Get rid of the f variable.



import os

i = 0
while os.path.exists('myfile%04i.txt' % i):
i += 1





share|improve this answer


























  • Oh great! But I still need f at the end, is there a way to get it?

    – Basj
    Nov 27 '18 at 14:36











  • Make f a variable and "give" it to while.

    – Ctrl S
    Nov 27 '18 at 14:37











  • @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

    – Bill the Lizard
    Nov 27 '18 at 14:39






  • 2





    The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

    – Basj
    Nov 27 '18 at 14:43













  • Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

    – Bill the Lizard
    Nov 27 '18 at 14:47



















0














I nearly found the answer while writing the end of the question. After a few modifications, it works:



import os
i = 0
while True:
f = 'myfile%04i.txt' % i
if not os.path.exists(f):
break
i += 1
print f


Still I wonder if there is a more pythonic way, maybe with an iterator, generator, next(...) or anything like this.






share|improve this answer































    0














    Is this too simple?



    import os
    f = 'myfile0000.txt'
    while os.path.exists(f):
    i += 1
    f = 'myfile%04i.txt' % i





    share|improve this answer
























    • It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

      – Basj
      Nov 27 '18 at 14:41



















    0














    You could do:



    import os
    from itertools import count

    cursor = count()
    it = iter((path for path in map(lambda x: 'myfile%04i.txt' % x, cursor) if not os.path.exists(path)))
    first = next(it, None)

    if first:
    print(first)


    Output



    myfile0000.txt





    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%2f53501978%2fhow-to-pythonically-avoid-this-code-duplication-with-a-while-loop%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      5 Answers
      5






      active

      oldest

      votes








      5 Answers
      5






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      6














      You do not need to follow the while paradiagm here, a nested generator expression with next() works:



      import os
      from itertools import count
      f = next(f for f in ('myfile%04i.txt' % i for i in count()) if not os.path.exists(f))
      print(f)





      share|improve this answer


























      • Perfect solution (I just edited so that we can easily test it by copying/pasting).

        – Basj
        Nov 27 '18 at 14:46











      • @Basj ok, note I just edited it a bit to correct a mistake (of mine)

        – Chris_Rands
        Nov 27 '18 at 14:47








      • 1





        This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

        – Basj
        Nov 27 '18 at 14:49
















      6














      You do not need to follow the while paradiagm here, a nested generator expression with next() works:



      import os
      from itertools import count
      f = next(f for f in ('myfile%04i.txt' % i for i in count()) if not os.path.exists(f))
      print(f)





      share|improve this answer


























      • Perfect solution (I just edited so that we can easily test it by copying/pasting).

        – Basj
        Nov 27 '18 at 14:46











      • @Basj ok, note I just edited it a bit to correct a mistake (of mine)

        – Chris_Rands
        Nov 27 '18 at 14:47








      • 1





        This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

        – Basj
        Nov 27 '18 at 14:49














      6












      6








      6







      You do not need to follow the while paradiagm here, a nested generator expression with next() works:



      import os
      from itertools import count
      f = next(f for f in ('myfile%04i.txt' % i for i in count()) if not os.path.exists(f))
      print(f)





      share|improve this answer















      You do not need to follow the while paradiagm here, a nested generator expression with next() works:



      import os
      from itertools import count
      f = next(f for f in ('myfile%04i.txt' % i for i in count()) if not os.path.exists(f))
      print(f)






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 27 '18 at 14:47

























      answered Nov 27 '18 at 14:44









      Chris_RandsChris_Rands

      16.8k54075




      16.8k54075













      • Perfect solution (I just edited so that we can easily test it by copying/pasting).

        – Basj
        Nov 27 '18 at 14:46











      • @Basj ok, note I just edited it a bit to correct a mistake (of mine)

        – Chris_Rands
        Nov 27 '18 at 14:47








      • 1





        This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

        – Basj
        Nov 27 '18 at 14:49



















      • Perfect solution (I just edited so that we can easily test it by copying/pasting).

        – Basj
        Nov 27 '18 at 14:46











      • @Basj ok, note I just edited it a bit to correct a mistake (of mine)

        – Chris_Rands
        Nov 27 '18 at 14:47








      • 1





        This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

        – Basj
        Nov 27 '18 at 14:49

















      Perfect solution (I just edited so that we can easily test it by copying/pasting).

      – Basj
      Nov 27 '18 at 14:46





      Perfect solution (I just edited so that we can easily test it by copying/pasting).

      – Basj
      Nov 27 '18 at 14:46













      @Basj ok, note I just edited it a bit to correct a mistake (of mine)

      – Chris_Rands
      Nov 27 '18 at 14:47







      @Basj ok, note I just edited it a bit to correct a mistake (of mine)

      – Chris_Rands
      Nov 27 '18 at 14:47






      1




      1





      This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

      – Basj
      Nov 27 '18 at 14:49





      This is really pythonic, concise, and explicit! I thought it would be possible with a generator / next() but I didn't find how to do it, thanks a lot!

      – Basj
      Nov 27 '18 at 14:49













      3














      Get rid of the f variable.



      import os

      i = 0
      while os.path.exists('myfile%04i.txt' % i):
      i += 1





      share|improve this answer


























      • Oh great! But I still need f at the end, is there a way to get it?

        – Basj
        Nov 27 '18 at 14:36











      • Make f a variable and "give" it to while.

        – Ctrl S
        Nov 27 '18 at 14:37











      • @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

        – Bill the Lizard
        Nov 27 '18 at 14:39






      • 2





        The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

        – Basj
        Nov 27 '18 at 14:43













      • Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

        – Bill the Lizard
        Nov 27 '18 at 14:47
















      3














      Get rid of the f variable.



      import os

      i = 0
      while os.path.exists('myfile%04i.txt' % i):
      i += 1





      share|improve this answer


























      • Oh great! But I still need f at the end, is there a way to get it?

        – Basj
        Nov 27 '18 at 14:36











      • Make f a variable and "give" it to while.

        – Ctrl S
        Nov 27 '18 at 14:37











      • @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

        – Bill the Lizard
        Nov 27 '18 at 14:39






      • 2





        The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

        – Basj
        Nov 27 '18 at 14:43













      • Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

        – Bill the Lizard
        Nov 27 '18 at 14:47














      3












      3








      3







      Get rid of the f variable.



      import os

      i = 0
      while os.path.exists('myfile%04i.txt' % i):
      i += 1





      share|improve this answer















      Get rid of the f variable.



      import os

      i = 0
      while os.path.exists('myfile%04i.txt' % i):
      i += 1






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 27 '18 at 14:47

























      answered Nov 27 '18 at 14:35









      Bill the LizardBill the Lizard

      294k157498789




      294k157498789













      • Oh great! But I still need f at the end, is there a way to get it?

        – Basj
        Nov 27 '18 at 14:36











      • Make f a variable and "give" it to while.

        – Ctrl S
        Nov 27 '18 at 14:37











      • @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

        – Bill the Lizard
        Nov 27 '18 at 14:39






      • 2





        The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

        – Basj
        Nov 27 '18 at 14:43













      • Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

        – Bill the Lizard
        Nov 27 '18 at 14:47



















      • Oh great! But I still need f at the end, is there a way to get it?

        – Basj
        Nov 27 '18 at 14:36











      • Make f a variable and "give" it to while.

        – Ctrl S
        Nov 27 '18 at 14:37











      • @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

        – Bill the Lizard
        Nov 27 '18 at 14:39






      • 2





        The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

        – Basj
        Nov 27 '18 at 14:43













      • Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

        – Bill the Lizard
        Nov 27 '18 at 14:47

















      Oh great! But I still need f at the end, is there a way to get it?

      – Basj
      Nov 27 '18 at 14:36





      Oh great! But I still need f at the end, is there a way to get it?

      – Basj
      Nov 27 '18 at 14:36













      Make f a variable and "give" it to while.

      – Ctrl S
      Nov 27 '18 at 14:37





      Make f a variable and "give" it to while.

      – Ctrl S
      Nov 27 '18 at 14:37













      @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

      – Bill the Lizard
      Nov 27 '18 at 14:39





      @Basj Yes, you could still initialize f before the loop, then use while os.path.exists(f % i)

      – Bill the Lizard
      Nov 27 '18 at 14:39




      2




      2





      The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

      – Basj
      Nov 27 '18 at 14:43







      The second solution doesn't work, if you print f, you'll get myfile%04i.txt and not myfile0002.txt for example. So we would need to add f = f % i at the end to really get the answer in f. It's probably the best solution so far though!

      – Basj
      Nov 27 '18 at 14:43















      Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

      – Bill the Lizard
      Nov 27 '18 at 14:47





      Ah, you're right. My bad for not running it. I'm going to revert my edit, since that's essentially what you started with.

      – Bill the Lizard
      Nov 27 '18 at 14:47











      0














      I nearly found the answer while writing the end of the question. After a few modifications, it works:



      import os
      i = 0
      while True:
      f = 'myfile%04i.txt' % i
      if not os.path.exists(f):
      break
      i += 1
      print f


      Still I wonder if there is a more pythonic way, maybe with an iterator, generator, next(...) or anything like this.






      share|improve this answer




























        0














        I nearly found the answer while writing the end of the question. After a few modifications, it works:



        import os
        i = 0
        while True:
        f = 'myfile%04i.txt' % i
        if not os.path.exists(f):
        break
        i += 1
        print f


        Still I wonder if there is a more pythonic way, maybe with an iterator, generator, next(...) or anything like this.






        share|improve this answer


























          0












          0








          0







          I nearly found the answer while writing the end of the question. After a few modifications, it works:



          import os
          i = 0
          while True:
          f = 'myfile%04i.txt' % i
          if not os.path.exists(f):
          break
          i += 1
          print f


          Still I wonder if there is a more pythonic way, maybe with an iterator, generator, next(...) or anything like this.






          share|improve this answer













          I nearly found the answer while writing the end of the question. After a few modifications, it works:



          import os
          i = 0
          while True:
          f = 'myfile%04i.txt' % i
          if not os.path.exists(f):
          break
          i += 1
          print f


          Still I wonder if there is a more pythonic way, maybe with an iterator, generator, next(...) or anything like this.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 27 '18 at 14:35









          BasjBasj

          6,26632107233




          6,26632107233























              0














              Is this too simple?



              import os
              f = 'myfile0000.txt'
              while os.path.exists(f):
              i += 1
              f = 'myfile%04i.txt' % i





              share|improve this answer
























              • It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

                – Basj
                Nov 27 '18 at 14:41
















              0














              Is this too simple?



              import os
              f = 'myfile0000.txt'
              while os.path.exists(f):
              i += 1
              f = 'myfile%04i.txt' % i





              share|improve this answer
























              • It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

                – Basj
                Nov 27 '18 at 14:41














              0












              0








              0







              Is this too simple?



              import os
              f = 'myfile0000.txt'
              while os.path.exists(f):
              i += 1
              f = 'myfile%04i.txt' % i





              share|improve this answer













              Is this too simple?



              import os
              f = 'myfile0000.txt'
              while os.path.exists(f):
              i += 1
              f = 'myfile%04i.txt' % i






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 27 '18 at 14:39









              DominiqueDominique

              1,96141841




              1,96141841













              • It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

                – Basj
                Nov 27 '18 at 14:41



















              • It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

                – Basj
                Nov 27 '18 at 14:41

















              It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

              – Basj
              Nov 27 '18 at 14:41





              It "works", like my question's code, and the solution I posted, but I wanted to know if there is a solution without duplication of f = ....

              – Basj
              Nov 27 '18 at 14:41











              0














              You could do:



              import os
              from itertools import count

              cursor = count()
              it = iter((path for path in map(lambda x: 'myfile%04i.txt' % x, cursor) if not os.path.exists(path)))
              first = next(it, None)

              if first:
              print(first)


              Output



              myfile0000.txt





              share|improve this answer




























                0














                You could do:



                import os
                from itertools import count

                cursor = count()
                it = iter((path for path in map(lambda x: 'myfile%04i.txt' % x, cursor) if not os.path.exists(path)))
                first = next(it, None)

                if first:
                print(first)


                Output



                myfile0000.txt





                share|improve this answer


























                  0












                  0








                  0







                  You could do:



                  import os
                  from itertools import count

                  cursor = count()
                  it = iter((path for path in map(lambda x: 'myfile%04i.txt' % x, cursor) if not os.path.exists(path)))
                  first = next(it, None)

                  if first:
                  print(first)


                  Output



                  myfile0000.txt





                  share|improve this answer













                  You could do:



                  import os
                  from itertools import count

                  cursor = count()
                  it = iter((path for path in map(lambda x: 'myfile%04i.txt' % x, cursor) if not os.path.exists(path)))
                  first = next(it, None)

                  if first:
                  print(first)


                  Output



                  myfile0000.txt






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 27 '18 at 14:40









                  Daniel MesejoDaniel Mesejo

                  18.6k21432




                  18.6k21432






























                      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%2f53501978%2fhow-to-pythonically-avoid-this-code-duplication-with-a-while-loop%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

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

                      Calculate evaluation metrics using cross_val_predict sklearn

                      Insert data from modal to MySQL (multiple modal on website)