Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python3中使用递归查找列表列表中的第二小int_Python_Recursion - Fatal编程技术网

在Python3中使用递归查找列表列表中的第二小int

在Python3中使用递归查找列表列表中的第二小int,python,recursion,Python,Recursion,我想在可能存在空列表的列表中找到第二个最小的int。我在平坦的台阶上卡住了 我的想法 未排序的列表,例如[1,3,2]、[4]、[12,12]、[12]、[12]、[12]、[12]、[12]、[12]、[4]、[4]、[4]、[12]、[12]、[12]、[12]、[12]、[12]、[12]、[12]、[4 结巴!!!!!!使用纯递归将列表展平。我在递归步骤的第一部分中尝试过这样做。上面的例子变成[1,3,2,4],[12,12,12] 查找第二个最小整数(已完成) 这是密码 def fin

我想在可能存在空列表的列表中找到第二个最小的int。我在平坦的台阶上卡住了

我的想法

  • 未排序的列表,例如[1,3,2]、[4]、[12,12]、[12]、[12]、[12]、[12]、[12]、[12]、[4]、[4]、[4]、[12]、[12]、[12]、[12]、[12]、[12]、[12]、[12]、[4

  • 结巴!!!!!!使用纯递归将列表展平。我在递归步骤的第一部分中尝试过这样做。上面的例子变成[1,3,2,4],[12,12,12]

  • 查找第二个最小整数(已完成)

  • 这是密码

    def find(abc):
    #base case
    if len(abc) == 2:
        if isinstance(abc[0], list) and isinstance(abc[1], list):
            re = find(abc[0] + abc[1])
        elif isinstance(abc[1], list):
            re = find(abc[:1] + abc[1])
        elif isinstance(abc[0], list):
            first = find(abc[0] + abc[1:])
        else:
            if abc[0] > abc[1]:
                re = (abc[0], abc[1])
            else:
                re = (abc[1], abc[0])
    # recursive step
    else:
        #i think this part has problem 
        # flatten the list
        if isinstance(abc[0], list):
            re = find(abc[0] + abc[1:])
        # if this element is interger
        else:
            current = abc[0]
            second, first = find(abc[1:])
            if (second < current):
                re = (second, first)
            elif (current > first) and (second >= current):
                re = (current, first)
            else:
                re = (first, current)            
    return re
    e.g   find([[[]], [12, 12], [[12], []], [[]]]) -> (12, 12)
          find([1, [2, 3], [[]], [4]]) -> (2, 1)
    
    def find(abc):
    #基本情况
    如果len(abc)==2:
    如果isinstance(abc[0],列表)和isinstance(abc[1],列表):
    re=find(abc[0]+abc[1])
    elif isinstance(abc[1],列表):
    re=查找(abc[:1]+abc[1])
    elif isinstance(abc[0],列表):
    第一个=查找(abc[0]+abc[1:])
    其他:
    如果abc[0]>abc[1]:
    re=(abc[0],abc[1])
    其他:
    re=(abc[1],abc[0])
    #递归步骤
    其他:
    #我认为这部分有问题
    #将列表展平
    如果存在(abc[0],列表):
    re=find(abc[0]+abc[1:])
    #如果这个元素是整数
    其他:
    当前=abc[0]
    第二,第一=查找(abc[1:])
    如果(秒<电流):
    re=(第二,第一)
    elif(当前>第一)和(第二>=当前):
    re=(当前,第一个)
    其他:
    re=(第一,当前)
    返回re
    e、 g查找([[]],[12,12],[12],[[]],[[[]]])->(12,12)
    查找([1,2,3],[]],[4]])->(2,1)
    
    遍历列表,然后使用
    isinstance
    检查是否需要递归:

    def MIN(lst):
       mn = None
       for item in lst:
           if isinstance(item, list) and item:
               tmp = MIN(item)
           else:
               tmp = item
    
           if not mn:
              mn = tmp
           elif mn > tmp:
               mn = tmp
       return mn
    
    def find(lst):
      mins = []
      if not all(isinstance(item, list) for item in lst):
         mins.append(MIN(lst))
      for item in lst:
         if isinstance(item, list):
            mins.append(MIN(item))
      return filter(lambda x: x==0 or x, mins)
    
    print find([[[]], [12, 12], [[12], []], [[]]])
    print find([1, [2, 3], [[]], [4]])
    

    正在解决问题: 您必须在递归中处理空列表的情况。对您的代码进行一个最小的(并且承认有点骇人的)更改将如下所示:

    import sys 
    
    def find(abc):
        #base case
        if len(abc) == 2:
            if isinstance(abc[0], list) and isinstance(abc[1], list):
                re = find(abc[0] + abc[1:])
            elif isinstance(abc[1], list):
                re = find(abc[:1] + abc[1])
            elif isinstance(abc[0], list):
                re = find(abc[0] + abc[1:])
                # ^^^ fixed typo (ifs could be simplified by dropping first if)
            else:
                if abc[0] > abc[1]:
                    re = (abc[0], abc[1])
                else:
                    re = (abc[1], abc[0])
        # recursive step
        else:
            # CHANGE HERE
            if len(abc) == 0:   # @HACK: handle empty list
                return (sys.maxsize, sys.maxsize)
            # CHANGE ENDS
            if isinstance(abc[0], list):
                re = find(abc[0] + abc[1:])
            # if this element is integer
            else:
                current = abc[0]
                second, first = find(abc[1:])
                if (second < current):
                    re = (second, first)
                elif (current > first) and (second >= current):
                    re = (current, first)
                else:
                    re = (first, current)            
        return re # @TODO: possibly filter out maxsize in final result
    
    如果您对稍微不同的返回值感到满意,可以随意删除
    元组
    [:-1]

    替代实施方案: 虽然出于各种原因(例如健壮性、表达能力),我更喜欢上面的重构代码,但这里有一个替代实现,可以说更符合您最初的问题。这个实现背后的主要思想是只检查第一个元素是否是列表?如果是,请展平;如果否,则递归地转到列表的末尾:

    def find(abc):
        try:                                                          # first element is list
            return find(abc[0] + abc[1:])                             #  -> flatten
        except:                                                       # first element is value
            if len(abc) <= 1: return abc                              # -> either end recursion
            return sorted(abc[:1] + find(abc[1:]), reverse=True)[-2:] # -> or recurse over tail
    
    def find(abc):
    try:#第一个元素是list
    返回查找(abc[0]+abc[1:])#->展平
    除此之外:#第一个元素是值
    如果len(abc)任一端递归
    返回排序(abc[:1]+查找(abc[1]),reverse=True)[-2:]#->或在尾部递归
    

    请注意,返回类型略有不同(列表而不是元组)。您可以用
    heapq.nsmallest
    替换
    sorted
    (这对于较小的
    n
    )更有效。

    如果您的用例很大,并且希望避免递归,您可以执行一些迭代魔法并避免递归:

    def nested_walker(data):
        working_iterators = [iter(data)]
        while working_iterators:
            current_iterator = working_iterators.pop()
            for elem in current_iterator:
                if isinstance(elem, list):
                    working_iterators.append(iter(elem))
                else:
                    yield elem
    
    然后,你可以做如下事情:

    data = [[1, [3, 2], [[]], [4]],[[]], [12, 12], [[12], []], [[]]]
    sorted_list = sorted(nested_walker(data))
    print sorted_list[1]
    
    有更智能的方法来检索第二个最小的整数。为了避免对潜在的巨大大小进行排序,可以使用嵌套的_walker being,因为它是一个生成器函数


    正如@stephan所指出的,有一种方法可以使用
    heapq
    ,避免排序:

    data = [[1, [3, 2], [[]], [4]],[[]], [12, 12], [[12], []], [[]]]
    two_mins = heapq.nsmallest(2, nested_walker(data))
    print two_mins[1]  # the [0] is the minimum
    

    这是值得检查的,因为它在性能方面可能有点棘手。

    这里是Python 3中的一个解决方案,它将列表展平、排序并最终返回结果的第二个最小项:

    import collections
    
    def flatten(l):
        for el in l:
            if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
                for sub in flatten(el):
                    yield sub
            else:
                yield el
    
    a = flatten([[[]], [12, 12], [[12], []], [[]]])
    b = flatten([1, [2, 3], [[]], [4]])
    
    print(sorted(a)[1]) # 12
    print(sorted(b)[1]) # 2
    

    flatten
    功能被直接从中窃取。对于Python 2.7,在
    flatten

    中将
    (str,bytes)
    替换为
    basestring
    ,您的确切问题是什么?它无法处理空列表的列表,因此如果len(abc)==0,请添加另一个条件
    :return
    如果存在重复值,请考虑所需的行为。例如:
    data=[1,1,2,3]
    应该导致
    1
    2
    ?我刚刚意识到,当我想处理空列表时,我忘记了处理空列表。@InWind:很高兴这有帮助。一天后回顾您的问题,我想您可能也对一个简单的递归实现感兴趣(我现在在回答的末尾添加了这个实现)。+1我喜欢这个解决方案。为了避免对一个巨大的列表进行排序,您可以简单地使用
    def find(abc):返回heapq.nsmallest(2,嵌套的\u walker(abc))
    。我确信
    heapq
    有一些方法可以使用,但很匆忙。我现在会更新答案,谢谢!
    data = [[1, [3, 2], [[]], [4]],[[]], [12, 12], [[12], []], [[]]]
    two_mins = heapq.nsmallest(2, nested_walker(data))
    print two_mins[1]  # the [0] is the minimum
    
    import collections
    
    def flatten(l):
        for el in l:
            if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
                for sub in flatten(el):
                    yield sub
            else:
                yield el
    
    a = flatten([[[]], [12, 12], [[12], []], [[]]])
    b = flatten([1, [2, 3], [[]], [4]])
    
    print(sorted(a)[1]) # 12
    print(sorted(b)[1]) # 2