Python 最小迭代的列表操作

Python 最小迭代的列表操作,python,list,iteration,Python,List,Iteration,假设您有以下两个列表: l1 = [0,30,45,55,80,90] l2 = [35,65,70,75,100,120] 列表规则: `l1`始终从0开始,`l2`必须从大于0开始 列表必须按从最小到最大的顺序排列 目标: 从本质上说,每个数字都是某事物开始和结束的索引。目标是返回l2中的项目,以关闭l1中的第一个项目 说明: l2中的项目将“关闭”小于自身的最接近数字的l1中的项目。那么这两个数字都不再可用了。以给出的列表为例,将发生以下情况: 0打开 30开 35分钟结束30分钟 45

假设您有以下两个列表:

l1 = [0,30,45,55,80,90]
l2 = [35,65,70,75,100,120]
列表规则:

  • `l1`始终从0开始,`l2`必须从大于0开始
  • 列表必须按从最小到最大的顺序排列
  • 目标:

    从本质上说,每个数字都是某事物开始和结束的索引。目标是返回
    l2
    中的项目,以关闭
    l1中的第一个项目

    说明:

    l2
    中的项目将“关闭”小于自身的最接近数字的
    l1
    中的项目。那么这两个数字都不再可用了。以给出的列表为例,将发生以下情况:

    0打开

    30开

    35分钟结束30分钟

    45开

    55开

    65结束55

    70结束45

    75比0

    答案=75

    我相信有一种方法可以做到这一点,只需遍历每个列表一次。我所提出的方法,需要迭代
    l1
    尽可能多的次数。所以在这个例子中,它必须迭代4次才能得到正确的答案。以下是该函数:

    def f(l1,l2):
        for x in l2:
            new_l = [i for i in l1 if i < x]
            closed = new_l[-1]
            if closed == 0:
                answer = x
                break
            else:
                l1.remove(closed)
        return answer
    
    定义f(l1,l2): 对于l2中的x: new_l=[如果i
    是否有任何方法可以检测什么关闭了什么,这样我就不需要重复多次。在我的实际情况中,这可能需要数百次迭代,因为这个函数实际上将在一个循环中运行,这个循环可能会持续一段时间

    def findBiggest(L, val):
        """ Basically a modified binary search """
        if len(L) == 1:
            return L[0]
        elif L[len(L)/2] >= val:
            return biggest(L[:len(L)/2], val)
        else:
            return findBiggest(L[len(L)/2:], val)
    
    def findOpens(opens, closes):
        for c in closes:
            opener = findBiggest(opens, c)
            opens.remove(opener)
            if opener == 0:
                print 'answer =', c
                return opener
    
    这对你有用吗

    def findBiggest(L, val):
        """ Basically a modified binary search """
        if len(L) == 1:
            return L[0]
        elif L[len(L)/2] >= val:
            return biggest(L[:len(L)/2], val)
        else:
            return findBiggest(L[len(L)/2:], val)
    
    def findOpens(opens, closes):
        for c in closes:
            opener = findBiggest(opens, c)
            opens.remove(opener)
            if opener == 0:
                print 'answer =', c
                return opener
    

    您可以使用对分模块:

    import bisect
    def f(l1,l2):
        for x in l2:
            ind = bisect.bisect(l1,x)
            # if the index where the item from l2 can fit in l1 is 1,
            # then it's time to return 
            if ind - 1 == 0:           
                return x
            del l1[ind-1]   #otherwise remove the item from l1
    
    
    l1 = [0,30,45,55,80,90]
    l2 = [35,65,70,75,100,120]
    print f(l1,l2)
    #75
    

    您可以使用对分模块:

    import bisect
    def f(l1,l2):
        for x in l2:
            ind = bisect.bisect(l1,x)
            # if the index where the item from l2 can fit in l1 is 1,
            # then it's time to return 
            if ind - 1 == 0:           
                return x
            del l1[ind-1]   #otherwise remove the item from l1
    
    
    l1 = [0,30,45,55,80,90]
    l2 = [35,65,70,75,100,120]
    print f(l1,l2)
    #75
    

    这应该是
    O(N)
    中的技巧

     def find_answer(l1, l2):
        opened = 0
        curr_l2 = 0
    
        for el in l1:
            if el > l2[curr_l2]:
                while curr_l2 < len(l2) and el > l2[curr_l2]:
                    if opened == 1:
                        return l2[curr_l2]
                    elif opened > 1:
                        # l2[curr_l2] closes an element.
                        opened -= 1
                        curr_l2 += 1
                    else:
                        # Noone left to close
                        return None
            # `el` opens
            opened += 1
       # Remaining elements to close left
       return None
    
    def find_答案(l1,l2):
    打开=0
    电流l2=0
    对于l1中的el:
    如果el>l2[当前l2]:
    而curr_l2l2[curr_l2]:
    如果打开==1:
    返回l2[当前l2]
    elif已打开>1:
    #l2[curr_l2]关闭元素。
    打开-=1
    电流l2+=1
    其他:
    #没有人要关门了
    一无所获
    #'el'打开
    打开+=1
    #左键关闭的剩余元素
    一无所获
    
    这应该是
    O(N)
    中的技巧

     def find_answer(l1, l2):
        opened = 0
        curr_l2 = 0
    
        for el in l1:
            if el > l2[curr_l2]:
                while curr_l2 < len(l2) and el > l2[curr_l2]:
                    if opened == 1:
                        return l2[curr_l2]
                    elif opened > 1:
                        # l2[curr_l2] closes an element.
                        opened -= 1
                        curr_l2 += 1
                    else:
                        # Noone left to close
                        return None
            # `el` opens
            opened += 1
       # Remaining elements to close left
       return None
    
    def find_答案(l1,l2):
    打开=0
    电流l2=0
    对于l1中的el:
    如果el>l2[当前l2]:
    而curr_l2l2[curr_l2]:
    如果打开==1:
    返回l2[当前l2]
    elif已打开>1:
    #l2[curr_l2]关闭元素。
    打开-=1
    电流l2+=1
    其他:
    #没有人要关门了
    一无所获
    #'el'打开
    打开+=1
    #左键关闭的剩余元素
    一无所获
    
    此问题是标准括号匹配问题的变体。主要区别在于,开启器和关闭器不是一个单一的序列,而是对开启器和关闭器进行编号,它们的顺序由编号定义。我们可以懒散地将它们合并到一个序列中,然后遍历该序列并保留未关闭的开启器的计数,直到找到第一个开启器的关闭器。这在O(n)中运行,其中n是第一个开瓶器的闭合器的索引

    def merge_iterator(openers, closers):
        """Goes through the openers and closers, merging the sequences.
    
        Yields (opener, 1) or (closer, -1) tuples, sorted by the values of the
        openers or closers. Each yield runs in O(1).
    
        """
        openers = iter(openers)
        closers = iter(closers)
        opener = next(openers)
        closer = next(closers)
        try:
            while True:
                if opener < closer:
                    yield opener, 1
                    opener = next(openers)
                else:
                    yield closer, -1
                    closer = next(closers)
        except StopIteration:
            # Ran out of openers. (We can't run out of closers first.)
            yield closer, -1
            for closer in closers:
                yield closer, -1
    
    def find_closer(openers, closers):
        merged_sequence = merge_iterator(openers, closers)
    
        # open the first opener
        unclosed = 1
        next(merged_sequence)
    
        # open and close openers until the first opener closes
        for item, change_in_unclosed in merged_sequence:
            unclosed += change_in_unclosed
            if not unclosed:
                # We closed the first opener. Return the closer.
                return item
    
    def merge_迭代器(开启器、关闭器):
    “”遍历打开器和关闭器,合并序列。
    产生(opener,1)或(closer,-1)元组,按
    开瓶器或闭口器。每个产量在O(1)中运行。
    """
    开启器=iter(开启器)
    闭合器=iter(闭合器)
    开启器=下一个(开启器)
    关闭=下一个(关闭器)
    尝试:
    尽管如此:
    如果开启器<关闭器:
    产量开启器,1
    开启器=下一个(开启器)
    其他:
    收益率更接近-1
    关闭=下一个(关闭器)
    除停止迭代外:
    #开瓶器用完了。(我们不能先用完闭门器。)
    收益率更接近-1
    对于闭合器:
    收益率更接近-1
    def find_closer(开启器、关闭器):
    合并序列=合并迭代器(开始、结束)
    #打开第一个开瓶器
    未关闭=1
    下一步(合并的\u序列)
    #打开并关闭开瓶器,直到第一个开瓶器关闭
    对于项目,按合并顺序更改\u中的\u未关闭的\u:
    未关闭+=未关闭中的更改
    如果未关闭:
    #我们结束了第一个开场白。再靠近一点。
    退货项目
    
    此问题是标准括号匹配问题的变体。主要区别在于,开启器和关闭器不是一个单一的序列,而是对开启器和关闭器进行编号,它们的顺序由编号定义。我们可以懒散地将它们合并到一个序列中,然后遍历该序列并保留未关闭的开启器的计数,直到找到第一个开启器的关闭器。这在O(n)中运行,其中n是第一个开瓶器的闭合器的索引

    def merge_iterator(openers, closers):
        """Goes through the openers and closers, merging the sequences.
    
        Yields (opener, 1) or (closer, -1) tuples, sorted by the values of the
        openers or closers. Each yield runs in O(1).
    
        """
        openers = iter(openers)
        closers = iter(closers)
        opener = next(openers)
        closer = next(closers)
        try:
            while True:
                if opener < closer:
                    yield opener, 1
                    opener = next(openers)
                else:
                    yield closer, -1
                    closer = next(closers)
        except StopIteration:
            # Ran out of openers. (We can't run out of closers first.)
            yield closer, -1
            for closer in closers:
                yield closer, -1
    
    def find_closer(openers, closers):
        merged_sequence = merge_iterator(openers, closers)
    
        # open the first opener
        unclosed = 1
        next(merged_sequence)
    
        # open and close openers until the first opener closes
        for item, change_in_unclosed in merged_sequence:
            unclosed += change_in_unclosed
            if not unclosed:
                # We closed the first opener. Return the closer.
                return item
    
    def merge_迭代器(开启器、关闭器):
    “”遍历打开器和关闭器,合并序列。
    产生(opener,1)或(closer,-1)元组,按
    开瓶器或闭口器。每个产量在O(1)中运行。
    """
    开启器=iter(开启器)
    闭合器=iter(闭合器)
    开启器=下一个(开启器)
    关闭=下一个(关闭器)
    尝试:
    尽管如此:
    如果开启器<关闭器:
    产量开启器,1
    开启器=下一个(开启器)
    其他:
    收益率更接近-1
    关闭=下一个(关闭器)
    除停止迭代外:
    #开瓶器用完了。(我们不能先用完闭门器。)
    产量氯