Finding craters [descending/ ascending ints] in a python list of ints
<p>I have a list of ints in python, and I would like the output to be a list of different "craters" in the sequence. I define a crater as a sequence of numbers that begins with descending ints that gradually grow bigger, until they reach a number that is equal to the first int of the crater or greater than the first int in the crater. 
If the last number is equal or smaller than the first - it should be in the output at the end of the crater. If the last number is greater than the first number in the crater - it should not be appended to the end of the output list.</p>

<p>For example, for the list: 
1,2,3,4,5,6,5,4,3,4,5,6,7,8,9
A "crater" would be:
6,5,4,3,4,5,6</p>

<p>My code:</p>

<pre><code>def find_crater(my_list):
cur_crater = []
for i in range(len(my_list)-1):
    #check if the numbers are decreasing
    if (my_list[i] - my_list[i+1] &gt; 0):
        cur_crater.append(my_list[i])
    #if increasing - check if we're in a crater 
    #and if current number is smaller than begining of crater
    elif len(cur_crater) &gt; 1 and my_list[i] &lt;= cur_crater[0]:
        cur_crater.append(my_list[i])
    #print crater and empty list 
    elif len(cur_crater) &gt; 1 and my_list[i+1] &gt; cur_crater[0]:
        print(cur_crater)
        cur_crater = []
    #continue if we're out of a crater
    else:
        continue
#catching the last crater in the list
if len(cur_crater) &gt; 1:
    #include last int
    if my_list[i] - my_list[-1] &lt; 0  and my_list[-1] &lt;= cur_crater[0]:
        cur_crater.append(my_list[-1])
    print(cur_crater)
return
</code></pre>

<p>I have called the function on 2 lists. The 1st output is as expected:</p>

<pre><code>ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23, 
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
</code></pre>

<p>Ok list output [edit: not so ok - it ommited the first '4' so turns out it's not so OK after all]: </p>

<pre><code>[12, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[28, 19, 17, 19, 21, 19, 12, 23, 25, 27]
</code></pre>

<p>However, the second list combines 2 lists of craters into 1 list in the output:</p>

<pre><code>problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23, 
24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 
17, 27, 19, 25, 19, 12, 23, 25, 27]
</code></pre>

<p>problematic Output:</p>

<pre><code>[12, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17, 27, 19, 25, 19, 12, 23, 25]
</code></pre>

<p>I was expecting: </p>

<pre><code>[12, 4, 7, 4, 2, 4, 5, 6, 5, 12]
[26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17]
[27, 19, 25, 19, 12, 23, 25, 27]
</code></pre>

<p>I tried to take care of this by writing: 
my_list[i+1] > cur_crater[0]
and thus checking the size of next int in the list - but that does not seem to fix it [I left it in the code even though it does not do the trick in hopes of someone explaining why is that wrong/ not working?].</p>

<p>In conclusion, my code can't handle it when there is a crater right after a crater with only one int in between. </p>

<p>If the input is: </p>

<p>[12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 10, 9, 8, 6, 9, 10]</p>

<p>Then the output is one long list, but I'd like to split it after list item 12 and before list item 21, but the output is one long list. </p>

<p>I would love to get info about any library or method that can give me more ideas regarding a better and more efficient solution. </p>

<p>Here is what I came with:</p>

<pre><code>def find_crater(my_list):
    previous = None
    current_crater = []
    crater_list = []
    for elem in my_list:

        #For the first element
        if not previous:
            previous = elem
            continue

        if len(current_crater) == 0:
            if elem &gt; previous:
                previous = elem
            else:
                current_crater.append(previous)
                previous = elem
        else:
            if elem &gt; current_crater[0]:
                current_crater.append(previous)
                crater_list.append(current_crater)
                current_crater = []
                previous = elem
            else:
                current_crater.append(previous)
                previous = elem

    if len(current_crater) != 0:
        if elem &gt; current_crater[0]:
            current_crater.append(previous)
            crater_list.append(current_crater)
        else:
            current_crater.append(previous)
            crater_list.append(current_crater)

    return crater_list
</code></pre>

<p>That gave me the exact output you want:</p>

<pre><code>In [5]: ok_list = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23, 
   ...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14,
   ...: 17, 27, 28, 19, 17, 19, 21, 19, 12, 23, 25, 27]

In [6]: find_crater(ok_list)
Out[6]: 
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12],
 [26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
 [28, 19, 17, 19, 21, 19, 12, 23, 25, 27]]

In [7]: problematic = [12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 23, 
   ...: 24, 26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 
   ...: 17, 27, 19, 25, 19, 12, 23, 25, 27]

In [8]: find_crater(problematic)
Out[8]: 
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12],
 [26, 25, 22, 10, 9, 8, 6, 9, 10, 11, 13, 12, 14, 17],
 [27, 19, 25, 19, 12, 23, 25, 27]]
</code></pre>

python list int