Decompose a list of integers into lists of increasing sequences

前端 未结 6 909
北恋
北恋 2020-12-20 04:33

Assume no consecutive integers are in the list.

I\'ve tried using NumPy (np.diff) for the difference between each element, but haven\'t been able to use

相关标签:
6条回答
  • 2020-12-20 05:11

    Here's a simple way to do what you're asking without any extra libraries:

    result_list = []
    sublist = []
    previous_number = None
    
    for current_number in inp:
        if previous_number is None or current_number > previous_number:
            # still ascending, add to the current sublist
            sublist.append(current_number)
        else:
            # no longer ascending, add the current sublist 
            result_list.append(sublist)
    
            # start a new sublist
            sublist = [current_number]
        previous_number = current_number
    if sublist:
        # add the last sublist, if there's anything there
        result_list.append(sublist)
    
    0 讨论(0)
  • 2020-12-20 05:23

    You could use itertools.zip_longest to enable iteration over sequential element pairs in your list along with enumerate to keep track of index values where the sequences are not increasing in order to append corresponding slices to your output list.

    from itertools import zip_longest
    
    nums = [1, 4, 1, 2, 4, 3, 5, 4, 0]
    
    results = []
    start = 0
    for i, (a, b) in enumerate(zip_longest(nums, nums[1:])):
        if b is None or b <= a:
            results.append(nums[start:i+1])
            start = i + 1
    
    print(results)
    # [[1, 4], [1, 2, 4], [3, 5], [4], [0]]
    
    0 讨论(0)
  • 2020-12-20 05:25

    Just cause I feel kind, this will also work with negative numbers.

    seq = [6, 0, 4, 8, 7, 6]
    seq_by_incr_groups = []  # Will hold the result
    incr_seq = []  # Needed to create groups of increasing values.
    previous_value = 0  # Needed to assert whether or not it's an increasing value. 
    for curr_value in seq: # Iterate over the list
        if curr_value > previous_value: # It's an increasing value and belongs to the group of increasing values.
            incr_seq.append(curr_value)
        else:  # It was lower, lets append the previous group of increasing values to the result and reset the group so that we can create a new one.
            if incr_seq:  # It could be that it's empty, in the case that the first number in the input list is a negative.
                seq_by_incr_groups.append(incr_seq)
            incr_seq = []
            incr_seq.append(curr_value)
        previous_value = curr_value # Needed so that we in the next iteration can assert that the value is increasing compared to the prior one.
    
    if incr_seq:  # Check if we have to add any more increasing number groups.
        seq_by_incr_groups.append(incr_seq)  # Add them.
    
    print(seq_by_incr_groups)
    
    0 讨论(0)
  • 2020-12-20 05:33

    Below code should help you. However I would recommend that you use proper nomenclature and consider handling corner cases:

    li1 = [6, 0, 4, 8, 7, 6]
    li2 = [1, 4, 1, 2, 4, 3, 5, 4, 0]
    
    def inc_seq(li1):
      lix = []
      li_t = [] 
      for i in range(len(li1)):
        #print (i)
        if i < (len(li1) - 1) and li1[i] >= li1[i + 1]:
          li_t.append(li1[i])
          lix.append(li_t)
          li_t = []
        else:
          li_t.append(li1[i])
    
    
      print (lix)
    
    inc_seq(li1)
    inc_seq(li2)
    
    0 讨论(0)
  • 2020-12-20 05:34

    You can write a simple script and you don't need numpy as far as I have understood your problem statement. Try the script below. I have tested it using Python 3.6.7 and Python 2.7.15+ on my Ubuntu machine.

    def breakIntoList(inp):
        if not inp:
            return []
    
        sublist = [inp[0]]
        output = []
        for a in inp[1:]:
            if a > sublist[-1]:
                sublist.append(a)
            else:
                output.append(sublist);
                sublist = [a]
    
    
        output.append(sublist)
        return output
    
    
    
    list = [1, 4, 1, 2, 4, 3, 5, 4, 0]
    print(list)
    print(breakIntoList(list))
    

    Explanation:

    1. The script first checks if input List passed to it has one or more elements.
    2. It then initialise a sublist (variable name) to hold elements in increasing order. After that, we append input List's first element into our sublist.
    3. We iterate through the input List beginning from it's second element (Index: 1). We keep on checking if the current element in Input List is greater than last element of sublist (by sublist[-1]). If yes, we append the current element to our sublist (at the end). If not, it means we can't hold that current element in sub-List. We append the sublist to output List and clear the sublist (for holding other increasing order sublists) and add the current element to our sublist.
    4. At the end, we append the remaining sublist to the output List.
    0 讨论(0)
  • 2020-12-20 05:38

    Here's an alternative using dict, list comprehensions, and zip:

    seq = [1, 4, 1, 2, 4, 3, 5, 4, 0]
    dict_seq = {i:j for i,j in enumerate(seq)}
    
    # Get the index where numbers start to decrease
    idx = [0] # Adding a zero seems counter-intuitive now; we'll see the benefit later.
    for k, v in dict_seq.items():
        if k>0:
            if dict_seq[k]<dict_seq[k-1]:
                idx.append(k)
    
    # Using zip, slice and handling the last entry
    inc_seq = [seq[i:j] for i, j in zip(idx, idx[1:])] + [seq[idx[-1:]]]
    

    Output

    print(inc_seq)
    >>> [[1, 4], [1, 2, 4], [3, 5], [4], [0]]
    

    By initiating idx = [0] and creating 2 sublists idx, idx[1:], we can zip these sublists to form [0:2], [2:5], [5:7] and [7:8] with the list comprehension.

    >>> print(idx)
    >>> [0, 2, 5, 7, 8]
    
    >>> for i, j in zip(idx, idx[1:]):
           print('[{}:{}]'.format(i,j))
    
    [0:2]
    [2:5]
    [5:7]
    [7:8]   # <-- need to add the last slide [8:]
    
    0 讨论(0)
提交回复
热议问题