在一个python的int列表中查找陨石坑[下降/上升的int]

时间:2016-09-08 12:31:18

标签: python list int

我在python中有一个int列表,我希望输出是序列中不同“陨石坑”的列表。我将一个陨石坑定义为一系列数字,这些数字以逐渐增大的下降数开始,直到它们达到等于陨石坑的第一个int或大于陨石坑中的第一个int的数字。 如果最后一个数字等于或小于第一个数字 - 它应该位于火山口末端的输出中。如果最后一个数字大于火山口中的第一个数字 - 它不应该附加到输出列表的末尾。

例如,对于列表: 1,2,3,4,5,6,5,4,3,4,5,6,7,8,9 一个“陨石坑”将是: 6,5,4,3,4,5,6

我的代码:

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] > 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) > 1 and my_list[i] <= cur_crater[0]:
        cur_crater.append(my_list[i])
    #print crater and empty list 
    elif len(cur_crater) > 1 and my_list[i+1] > 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) > 1:
    #include last int
    if my_list[i] - my_list[-1] < 0  and my_list[-1] <= cur_crater[0]:
        cur_crater.append(my_list[-1])
    print(cur_crater)
return

我在2个列表上调用了该函数。第一个输出是预期的:

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]

好的列表输出[编辑:不太好 - 它忽略了第一个'4',所以结果发现它不是那么好了:

[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]

但是,第二个列表将2个陨石坑列表组合成输出中的1个列表:

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]

有问题的输出:

[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]

我在期待:

[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]

我试着通过写作来解决这个问题: my_list [i + 1]&gt; cur_crater [0] 然后检查列表中下一个int的大小 - 但这似乎没有解决它[我把它留在代码中,即使它没有做伎俩,希望有人解释为什么这是错误/不工作?]。

总之,当一个火山口后面只有一个int时,我的代码无法处理它。

如果输入为:

[12,4,7,4,2,4,5,6,5,12,21,10,9,8,6,9,10]

然后输出是一个长列表,但是我想在列表项12之后和列表项21之前拆分它,但是输出是一个长列表。

我很想获得有关任何图书馆或方法的信息,这些图书馆或方法可以为我提供更好,更有效的解决方案。

3 个答案:

答案 0 :(得分:0)

这是我的意思:

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 > previous:
                previous = elem
            else:
                current_crater.append(previous)
                previous = elem
        else:
            if elem > 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 > 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

这给了我你想要的确切输出:

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]]

答案 1 :(得分:0)

试试这个:

我们只是将列表发现from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium import webdriver driver = webdriver.Chrome() driver.set_script_timeout(10) driver.get("https://www.youtube.com/watch?v=hdw1uKiTI5c") # wait for video tag to show up wait = WebDriverWait(driver, 5) video = wait.until(EC.visibility_of_element_located((By.TAG_NAME, 'video'))) # wait for video to be initialized driver.execute_async_script(""" var video = arguments[0], callback = arguments[arguments.length - 1]; video.addEventListener('loadstart', listener); function listener() { callback(); }; """, video) # mute the video driver.execute_script("arguments[0].muted = true;", video) 切成三个案例

  • 当元素相等时
  • 当元素更大时
  • 最后一个元素即使较小的边界情况也可能需要切片
start_index:end_index

<强>输入:

def find_crater(l):    
    result = []
    start_index = 0
    for i in range( start_index +1,len(l)):
        start = l[start_index]
        if i==len(l)-1 and l[i]!=start:
            result = l[start_index:i+1]
            print result
        elif l[i]==start:
            end_index = i+1
            result = l[start_index:end_index]
            start_index = end_index +1
            if len(result)>1:
                print result
        elif l[i]>start:
            end_index = i
            result = l[start_index:end_index]
            start_index = end_index 
            if len(result)>1:
                print result

<强>输出:

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]

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]

答案 2 :(得分:0)

假设您的预期输出似乎是错误的,您要做的就是直到找到一个元素&gt; =到链的开头并捕获仅包含单个元素的链:

def craters(lst):
    it = iter(lst)
    # get start of first chain
    first = next(it)
    tmp = [first]
    # iterate over the remaining
    for ele in it:
        # >= ends chain
        if ele >= first:
            # if equal, add it and call
            #  next(it) to set the next first element.
            if ele == first:
                tmp.append(ele)
                yield tmp
                first = next(it)
                tmp = [first]
            # else yield the group if it has > 1 element.
            # if it has 1 element it is not a descending start sequecne
            else:
                if len(tmp) > 1:
                    yield tmp
                tmp = [ele]
                first = ele
        else:
            tmp.append(ele)
     if len(tmp) > 1: # catch single element last
         yield tmp

输出:

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]: 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 [7]: ex_ok = [[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 [8]: ex_p = [[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]]

In [9]: print(list(craters(problematic)) == ex_p)
True

In [10]: print(list(craters(ok_list)) == ex_ok)
True

In [11]: print(list(craters([12, 4, 7, 4, 2, 4, 5, 6, 5, 12, 21, 10, 9, 8, 6, 9, 10])))
[[12, 4, 7, 4, 2, 4, 5, 6, 5, 12], [21, 10, 9, 8, 6, 9, 10]]
In [12]: list(craters([1, 2, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 7, 8, 9]))
Out[13]: [[6, 5, 4, 3, 4, 5, 6]]

这不涉及任何切片/索引,你可以懒洋洋地返回每个组。

为简化算法,步骤如下:

  • 从第一个元素开始,然后检查下一个元素是否为> =,如果是,则相等,将其添加到组中,如果它是&gt;将其设置为该组的新开始

  • 如果新的第一个元素不大于下一个元素,则该组的长度将为1,因为它不满足以降序开头的数字序列。因此,我们继续使用并将下一个元素设置为序列的 first 元素,直到我们找到一个&gt;下一个元素,就是对next(it)的调用所做的事情,我们只需要清洗并重复。