Slicing a list into sublists based on condition

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite












I want to slice this list of numbers:



num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102] 


into multiple sublists. The condition for slicing is that the numbers in each sublist should be in increasing order.



So the final result will look like this:



 list_1 = [97, 122]
list_2 = [99]
list_3 = [98, 111, 112, 113]
list_4 = [100, 102]


Can anyone help me to solve this problem please? Thanks a lot










share|improve this question



























    up vote
    7
    down vote

    favorite












    I want to slice this list of numbers:



    num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102] 


    into multiple sublists. The condition for slicing is that the numbers in each sublist should be in increasing order.



    So the final result will look like this:



     list_1 = [97, 122]
    list_2 = [99]
    list_3 = [98, 111, 112, 113]
    list_4 = [100, 102]


    Can anyone help me to solve this problem please? Thanks a lot










    share|improve this question

























      up vote
      7
      down vote

      favorite









      up vote
      7
      down vote

      favorite











      I want to slice this list of numbers:



      num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102] 


      into multiple sublists. The condition for slicing is that the numbers in each sublist should be in increasing order.



      So the final result will look like this:



       list_1 = [97, 122]
      list_2 = [99]
      list_3 = [98, 111, 112, 113]
      list_4 = [100, 102]


      Can anyone help me to solve this problem please? Thanks a lot










      share|improve this question















      I want to slice this list of numbers:



      num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102] 


      into multiple sublists. The condition for slicing is that the numbers in each sublist should be in increasing order.



      So the final result will look like this:



       list_1 = [97, 122]
      list_2 = [99]
      list_3 = [98, 111, 112, 113]
      list_4 = [100, 102]


      Can anyone help me to solve this problem please? Thanks a lot







      python python-3.x list






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 42 mins ago









      jpp

      66.8k173984




      66.8k173984










      asked 1 hour ago









      Huy Nguyen Bui

      655




      655






















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          3
          down vote













          Here is a one-linear Numpythonic approach:



          np.split(arr, np.where(np.diff(arr) < 0)[0] + 1)


          Or a similar approach but less efficient in python:



          from operator import sub
          from itertools import starmap
          indices = [0] + [
          i+1 for i, j in enumerate(list(
          starmap(sub, zip(num_list[1:], num_list)))
          ) if j < 0] + [len(num_list)
          ] + [len(num_list)]

          result = [num_list[i:j] for i, j in zip(indices, indices[1:])]


          Demo:



          # Numpy
          In [8]: np.split(num_list, np.where(np.diff(num_list) < 0)[0] + 1)
          Out[8]:
          [array([ 97, 122]),
          array([99]),
          array([ 98, 111, 112, 113]),
          array([100, 102])]

          # Python
          In [42]: from operator import sub

          In [43]: from itertools import starmap

          In [44]: indices = [0] + [i+1 for i, j in enumerate(list(starmap(sub, zip(num_list[1:], num_list)))) if j < 0] + [len(num_list)]

          In [45]: [num_list[i:j] for i, j in zip(indices, indices[1:])]
          Out[45]: [[97, 122], [99], [98, 111, 112, 113], [100, 102]]


          Explanation:



          Using np.diff() you can get the differences of each item with their next item (up until the last element). Then you can use the vectorized nature of numpy to get the indices of the places where this difference is negative, which can be done with a simple comparison and np.where(). Finally you can simply pass the indices to np.split() to split the array based on those indices.






          share|improve this answer






















          • Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
            – Guimoute
            40 mins ago










          • @Guimoute There's no diff for last element. Just added that to the answer.
            – Kasrâmvd
            39 mins ago

















          up vote
          2
          down vote













          I've quickly written one way to do this, I'm sure there are more efficient ways, but this works at least:



          num_list =[97, 122, 99, 98, 111, 112, 113, 100, 102]

          arrays = [[num_list[0]]] # array of sub-arrays (starts with first value)
          for i in range(1, len(num_list)): # go through each element after the first
          if num_list[i - 1] < num_list[i]: # If it's larger than the previous
          arrays[len(arrays) - 1].append(num_list[i]) # Add it to the last sub-array
          else: # otherwise
          arrays.append([num_list[i]]) # Make a new sub-array
          print(arrays)


          Hopefully this helps you a bit :)






          share|improve this answer



























            up vote
            2
            down vote













            Creating a variable number of variables is not recommended. Use a list of lists or dictionary instead. Here's an example with dict and a generator function:



            from itertools import zip_longest

            def yield_lists(L):
            x =
            for i, j in zip_longest(L, L[1:], fillvalue=L[-1]):
            x.append(i)
            if i > j:
            yield x
            x =
            yield x

            num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102]

            res = dict(enumerate(yield_lists(num_list), 1))


            Resut:



            1: [97, 122],
            2: [99],
            3: [98, 111, 112, 113],
            4: [100, 102]


            For example, access the second list via res[2].






            share|improve this answer






















            • Ideal solution, generators for the win
              – Take_Care_
              41 mins ago

















            up vote
            0
            down vote













            All nice solutions here. Maybe this one will be easier to understand for some ppl?



            def increasing(a, b):
            return a < b

            def seq_split(lst, cond):
            sublst = [lst[0]]
            for item in lst[1:]:
            if cond(sublst[-1], item):
            sublst.append(item)
            else:
            yield sublst
            sublst = [item]
            if sublst:
            yield sublst

            list(seq_split(num_list, increasing))





            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',
              convertImagesToLinks: true,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              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%2f52551398%2fslicing-a-list-into-sublists-based-on-condition%23new-answer', 'question_page');

              );

              Post as a guest






























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              3
              down vote













              Here is a one-linear Numpythonic approach:



              np.split(arr, np.where(np.diff(arr) < 0)[0] + 1)


              Or a similar approach but less efficient in python:



              from operator import sub
              from itertools import starmap
              indices = [0] + [
              i+1 for i, j in enumerate(list(
              starmap(sub, zip(num_list[1:], num_list)))
              ) if j < 0] + [len(num_list)
              ] + [len(num_list)]

              result = [num_list[i:j] for i, j in zip(indices, indices[1:])]


              Demo:



              # Numpy
              In [8]: np.split(num_list, np.where(np.diff(num_list) < 0)[0] + 1)
              Out[8]:
              [array([ 97, 122]),
              array([99]),
              array([ 98, 111, 112, 113]),
              array([100, 102])]

              # Python
              In [42]: from operator import sub

              In [43]: from itertools import starmap

              In [44]: indices = [0] + [i+1 for i, j in enumerate(list(starmap(sub, zip(num_list[1:], num_list)))) if j < 0] + [len(num_list)]

              In [45]: [num_list[i:j] for i, j in zip(indices, indices[1:])]
              Out[45]: [[97, 122], [99], [98, 111, 112, 113], [100, 102]]


              Explanation:



              Using np.diff() you can get the differences of each item with their next item (up until the last element). Then you can use the vectorized nature of numpy to get the indices of the places where this difference is negative, which can be done with a simple comparison and np.where(). Finally you can simply pass the indices to np.split() to split the array based on those indices.






              share|improve this answer






















              • Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
                – Guimoute
                40 mins ago










              • @Guimoute There's no diff for last element. Just added that to the answer.
                – Kasrâmvd
                39 mins ago














              up vote
              3
              down vote













              Here is a one-linear Numpythonic approach:



              np.split(arr, np.where(np.diff(arr) < 0)[0] + 1)


              Or a similar approach but less efficient in python:



              from operator import sub
              from itertools import starmap
              indices = [0] + [
              i+1 for i, j in enumerate(list(
              starmap(sub, zip(num_list[1:], num_list)))
              ) if j < 0] + [len(num_list)
              ] + [len(num_list)]

              result = [num_list[i:j] for i, j in zip(indices, indices[1:])]


              Demo:



              # Numpy
              In [8]: np.split(num_list, np.where(np.diff(num_list) < 0)[0] + 1)
              Out[8]:
              [array([ 97, 122]),
              array([99]),
              array([ 98, 111, 112, 113]),
              array([100, 102])]

              # Python
              In [42]: from operator import sub

              In [43]: from itertools import starmap

              In [44]: indices = [0] + [i+1 for i, j in enumerate(list(starmap(sub, zip(num_list[1:], num_list)))) if j < 0] + [len(num_list)]

              In [45]: [num_list[i:j] for i, j in zip(indices, indices[1:])]
              Out[45]: [[97, 122], [99], [98, 111, 112, 113], [100, 102]]


              Explanation:



              Using np.diff() you can get the differences of each item with their next item (up until the last element). Then you can use the vectorized nature of numpy to get the indices of the places where this difference is negative, which can be done with a simple comparison and np.where(). Finally you can simply pass the indices to np.split() to split the array based on those indices.






              share|improve this answer






















              • Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
                – Guimoute
                40 mins ago










              • @Guimoute There's no diff for last element. Just added that to the answer.
                – Kasrâmvd
                39 mins ago












              up vote
              3
              down vote










              up vote
              3
              down vote









              Here is a one-linear Numpythonic approach:



              np.split(arr, np.where(np.diff(arr) < 0)[0] + 1)


              Or a similar approach but less efficient in python:



              from operator import sub
              from itertools import starmap
              indices = [0] + [
              i+1 for i, j in enumerate(list(
              starmap(sub, zip(num_list[1:], num_list)))
              ) if j < 0] + [len(num_list)
              ] + [len(num_list)]

              result = [num_list[i:j] for i, j in zip(indices, indices[1:])]


              Demo:



              # Numpy
              In [8]: np.split(num_list, np.where(np.diff(num_list) < 0)[0] + 1)
              Out[8]:
              [array([ 97, 122]),
              array([99]),
              array([ 98, 111, 112, 113]),
              array([100, 102])]

              # Python
              In [42]: from operator import sub

              In [43]: from itertools import starmap

              In [44]: indices = [0] + [i+1 for i, j in enumerate(list(starmap(sub, zip(num_list[1:], num_list)))) if j < 0] + [len(num_list)]

              In [45]: [num_list[i:j] for i, j in zip(indices, indices[1:])]
              Out[45]: [[97, 122], [99], [98, 111, 112, 113], [100, 102]]


              Explanation:



              Using np.diff() you can get the differences of each item with their next item (up until the last element). Then you can use the vectorized nature of numpy to get the indices of the places where this difference is negative, which can be done with a simple comparison and np.where(). Finally you can simply pass the indices to np.split() to split the array based on those indices.






              share|improve this answer














              Here is a one-linear Numpythonic approach:



              np.split(arr, np.where(np.diff(arr) < 0)[0] + 1)


              Or a similar approach but less efficient in python:



              from operator import sub
              from itertools import starmap
              indices = [0] + [
              i+1 for i, j in enumerate(list(
              starmap(sub, zip(num_list[1:], num_list)))
              ) if j < 0] + [len(num_list)
              ] + [len(num_list)]

              result = [num_list[i:j] for i, j in zip(indices, indices[1:])]


              Demo:



              # Numpy
              In [8]: np.split(num_list, np.where(np.diff(num_list) < 0)[0] + 1)
              Out[8]:
              [array([ 97, 122]),
              array([99]),
              array([ 98, 111, 112, 113]),
              array([100, 102])]

              # Python
              In [42]: from operator import sub

              In [43]: from itertools import starmap

              In [44]: indices = [0] + [i+1 for i, j in enumerate(list(starmap(sub, zip(num_list[1:], num_list)))) if j < 0] + [len(num_list)]

              In [45]: [num_list[i:j] for i, j in zip(indices, indices[1:])]
              Out[45]: [[97, 122], [99], [98, 111, 112, 113], [100, 102]]


              Explanation:



              Using np.diff() you can get the differences of each item with their next item (up until the last element). Then you can use the vectorized nature of numpy to get the indices of the places where this difference is negative, which can be done with a simple comparison and np.where(). Finally you can simply pass the indices to np.split() to split the array based on those indices.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 19 mins ago

























              answered 45 mins ago









              Kasrâmvd

              75.7k982115




              75.7k982115











              • Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
                – Guimoute
                40 mins ago










              • @Guimoute There's no diff for last element. Just added that to the answer.
                – Kasrâmvd
                39 mins ago
















              • Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
                – Guimoute
                40 mins ago










              • @Guimoute There's no diff for last element. Just added that to the answer.
                – Kasrâmvd
                39 mins ago















              Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
              – Guimoute
              40 mins ago




              Out of curiosity, what would be the last element of the np.diff(num_list) array? Because the last element has no next item.
              – Guimoute
              40 mins ago












              @Guimoute There's no diff for last element. Just added that to the answer.
              – Kasrâmvd
              39 mins ago




              @Guimoute There's no diff for last element. Just added that to the answer.
              – Kasrâmvd
              39 mins ago












              up vote
              2
              down vote













              I've quickly written one way to do this, I'm sure there are more efficient ways, but this works at least:



              num_list =[97, 122, 99, 98, 111, 112, 113, 100, 102]

              arrays = [[num_list[0]]] # array of sub-arrays (starts with first value)
              for i in range(1, len(num_list)): # go through each element after the first
              if num_list[i - 1] < num_list[i]: # If it's larger than the previous
              arrays[len(arrays) - 1].append(num_list[i]) # Add it to the last sub-array
              else: # otherwise
              arrays.append([num_list[i]]) # Make a new sub-array
              print(arrays)


              Hopefully this helps you a bit :)






              share|improve this answer
























                up vote
                2
                down vote













                I've quickly written one way to do this, I'm sure there are more efficient ways, but this works at least:



                num_list =[97, 122, 99, 98, 111, 112, 113, 100, 102]

                arrays = [[num_list[0]]] # array of sub-arrays (starts with first value)
                for i in range(1, len(num_list)): # go through each element after the first
                if num_list[i - 1] < num_list[i]: # If it's larger than the previous
                arrays[len(arrays) - 1].append(num_list[i]) # Add it to the last sub-array
                else: # otherwise
                arrays.append([num_list[i]]) # Make a new sub-array
                print(arrays)


                Hopefully this helps you a bit :)






                share|improve this answer






















                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  I've quickly written one way to do this, I'm sure there are more efficient ways, but this works at least:



                  num_list =[97, 122, 99, 98, 111, 112, 113, 100, 102]

                  arrays = [[num_list[0]]] # array of sub-arrays (starts with first value)
                  for i in range(1, len(num_list)): # go through each element after the first
                  if num_list[i - 1] < num_list[i]: # If it's larger than the previous
                  arrays[len(arrays) - 1].append(num_list[i]) # Add it to the last sub-array
                  else: # otherwise
                  arrays.append([num_list[i]]) # Make a new sub-array
                  print(arrays)


                  Hopefully this helps you a bit :)






                  share|improve this answer












                  I've quickly written one way to do this, I'm sure there are more efficient ways, but this works at least:



                  num_list =[97, 122, 99, 98, 111, 112, 113, 100, 102]

                  arrays = [[num_list[0]]] # array of sub-arrays (starts with first value)
                  for i in range(1, len(num_list)): # go through each element after the first
                  if num_list[i - 1] < num_list[i]: # If it's larger than the previous
                  arrays[len(arrays) - 1].append(num_list[i]) # Add it to the last sub-array
                  else: # otherwise
                  arrays.append([num_list[i]]) # Make a new sub-array
                  print(arrays)


                  Hopefully this helps you a bit :)







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 57 mins ago









                  DeltaMarine101

                  435315




                  435315




















                      up vote
                      2
                      down vote













                      Creating a variable number of variables is not recommended. Use a list of lists or dictionary instead. Here's an example with dict and a generator function:



                      from itertools import zip_longest

                      def yield_lists(L):
                      x =
                      for i, j in zip_longest(L, L[1:], fillvalue=L[-1]):
                      x.append(i)
                      if i > j:
                      yield x
                      x =
                      yield x

                      num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102]

                      res = dict(enumerate(yield_lists(num_list), 1))


                      Resut:



                      1: [97, 122],
                      2: [99],
                      3: [98, 111, 112, 113],
                      4: [100, 102]


                      For example, access the second list via res[2].






                      share|improve this answer






















                      • Ideal solution, generators for the win
                        – Take_Care_
                        41 mins ago














                      up vote
                      2
                      down vote













                      Creating a variable number of variables is not recommended. Use a list of lists or dictionary instead. Here's an example with dict and a generator function:



                      from itertools import zip_longest

                      def yield_lists(L):
                      x =
                      for i, j in zip_longest(L, L[1:], fillvalue=L[-1]):
                      x.append(i)
                      if i > j:
                      yield x
                      x =
                      yield x

                      num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102]

                      res = dict(enumerate(yield_lists(num_list), 1))


                      Resut:



                      1: [97, 122],
                      2: [99],
                      3: [98, 111, 112, 113],
                      4: [100, 102]


                      For example, access the second list via res[2].






                      share|improve this answer






















                      • Ideal solution, generators for the win
                        – Take_Care_
                        41 mins ago












                      up vote
                      2
                      down vote










                      up vote
                      2
                      down vote









                      Creating a variable number of variables is not recommended. Use a list of lists or dictionary instead. Here's an example with dict and a generator function:



                      from itertools import zip_longest

                      def yield_lists(L):
                      x =
                      for i, j in zip_longest(L, L[1:], fillvalue=L[-1]):
                      x.append(i)
                      if i > j:
                      yield x
                      x =
                      yield x

                      num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102]

                      res = dict(enumerate(yield_lists(num_list), 1))


                      Resut:



                      1: [97, 122],
                      2: [99],
                      3: [98, 111, 112, 113],
                      4: [100, 102]


                      For example, access the second list via res[2].






                      share|improve this answer














                      Creating a variable number of variables is not recommended. Use a list of lists or dictionary instead. Here's an example with dict and a generator function:



                      from itertools import zip_longest

                      def yield_lists(L):
                      x =
                      for i, j in zip_longest(L, L[1:], fillvalue=L[-1]):
                      x.append(i)
                      if i > j:
                      yield x
                      x =
                      yield x

                      num_list = [97, 122, 99, 98, 111, 112, 113, 100, 102]

                      res = dict(enumerate(yield_lists(num_list), 1))


                      Resut:



                      1: [97, 122],
                      2: [99],
                      3: [98, 111, 112, 113],
                      4: [100, 102]


                      For example, access the second list via res[2].







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 38 mins ago

























                      answered 50 mins ago









                      jpp

                      66.8k173984




                      66.8k173984











                      • Ideal solution, generators for the win
                        – Take_Care_
                        41 mins ago
















                      • Ideal solution, generators for the win
                        – Take_Care_
                        41 mins ago















                      Ideal solution, generators for the win
                      – Take_Care_
                      41 mins ago




                      Ideal solution, generators for the win
                      – Take_Care_
                      41 mins ago










                      up vote
                      0
                      down vote













                      All nice solutions here. Maybe this one will be easier to understand for some ppl?



                      def increasing(a, b):
                      return a < b

                      def seq_split(lst, cond):
                      sublst = [lst[0]]
                      for item in lst[1:]:
                      if cond(sublst[-1], item):
                      sublst.append(item)
                      else:
                      yield sublst
                      sublst = [item]
                      if sublst:
                      yield sublst

                      list(seq_split(num_list, increasing))





                      share|improve this answer
























                        up vote
                        0
                        down vote













                        All nice solutions here. Maybe this one will be easier to understand for some ppl?



                        def increasing(a, b):
                        return a < b

                        def seq_split(lst, cond):
                        sublst = [lst[0]]
                        for item in lst[1:]:
                        if cond(sublst[-1], item):
                        sublst.append(item)
                        else:
                        yield sublst
                        sublst = [item]
                        if sublst:
                        yield sublst

                        list(seq_split(num_list, increasing))





                        share|improve this answer






















                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          All nice solutions here. Maybe this one will be easier to understand for some ppl?



                          def increasing(a, b):
                          return a < b

                          def seq_split(lst, cond):
                          sublst = [lst[0]]
                          for item in lst[1:]:
                          if cond(sublst[-1], item):
                          sublst.append(item)
                          else:
                          yield sublst
                          sublst = [item]
                          if sublst:
                          yield sublst

                          list(seq_split(num_list, increasing))





                          share|improve this answer












                          All nice solutions here. Maybe this one will be easier to understand for some ppl?



                          def increasing(a, b):
                          return a < b

                          def seq_split(lst, cond):
                          sublst = [lst[0]]
                          for item in lst[1:]:
                          if cond(sublst[-1], item):
                          sublst.append(item)
                          else:
                          yield sublst
                          sublst = [item]
                          if sublst:
                          yield sublst

                          list(seq_split(num_list, increasing))






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 13 mins ago









                          code22

                          825




                          825



























                               

                              draft saved


                              draft discarded















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52551398%2fslicing-a-list-into-sublists-based-on-condition%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