Python 在列表中查找单调序列?

Python 在列表中查找单调序列?,python,for-loop,iteration,Python,For Loop,Iteration,我是Python新手,但基本上我希望通过双循环从列表中创建元素的子组,因此我将比较第一个元素和下一个元素,以确定是否可以创建这些子列表,否则我将在内部中断循环,并继续使用主循环中的最后一个元素: 示例:5,7,8,4,11 把5和7比较一下,是次要的吗?是的,所以包括在新列表中,并在里面继续下一个8,是不是小于5?是的,所以包括在newlist中,但是当与4比较时,我打破了循环,所以我想在m中继续使用这些4,从下一个开始,在本例中使用11 for m in xrange(len(path)):

我是Python新手,但基本上我希望通过双循环从列表中创建元素的子组,因此我将比较第一个元素和下一个元素,以确定是否可以创建这些子列表,否则我将在内部中断循环,并继续使用主循环中的最后一个元素:

示例:
5,7,8,4,11

把5和7比较一下,是次要的吗?是的,所以包括在新列表中,并在里面继续下一个8,是不是小于5?是的,所以包括在newlist中,但是当与4比较时,我打破了循环,所以我想在m中继续使用这些4,从下一个开始,在本例中使用11

for m in xrange(len(path)):
    for i in xrange(m+1,len(path)):
              if (path[i] > path[m]):
                  newlist.append(path[i])

             else:
                  break

             m=m+i
感谢您的建议或其他想法来实现它

附言。 一些投入将是: 输入:
[45,78120,47,58,50,32,34]
输出:
[45,78120]、[47,58]、50、[32,34]


我之所以要做一个双循环,是因为要比较完整列表的子组,换句话说,虽然45比下一个小,但只要添加到新列表中,如果没有,那么下一个要比较的将是47,并开始与58进行比较。

我也使用了双循环,但将内循环放入函数中:

#!/usr/bin/env python

def process(lst):

    def prefix(lst):
        pre = []
        while lst and (not pre or pre[-1] <= lst[0]):
            pre.append(lst[0])
            lst = lst[1:]
        return pre, lst

    res=[]
    while lst:
        subres, lst = prefix(lst)
        res.append(subres) 
    return res

print process([45,78,120,47,58,50,32,34])
=> [[45, 78, 120], [47, 58], [50], [32, 34]]


@uselpa的版本很好。这里是我的(与[50]相同的问题,而不是仅仅50个),它使用
collections.deque
来提高效率,还有一些长评论

#! /usr/bin/env python

from collections import deque

def process(lst):
    """
    Given a list of values that is not sorted (such that for some
    valid indices i,j, i<j, sometimes lst[i] > lst[j]), produce a
    new list-of-lists, such that in the new list, each sublist *is*
    sorted:
        for all sublist \elem returnval:
            assert_is_sorted(sublist)
    and furthermore this is the minimal set of sublists required
    to achieve the condition.

    Thus, if the input list lst is actually sorted, this returns
    [list(lst)].
    """
    def sublist(deq):
        """
        Pop items off the front of deque deq until the next one
        goes backwards.  Return the constructed sub-list.
        """
        sub = [deq.popleft()]
        while deq and deq[0] >= sub[-1]:
            sub.append(deq.popleft())
        return sub

    # Make a copy of lst before modifying it; use a deque so that
    # we can pull entries off it cheaply.
    deq = deque(lst)
    output = []
    ret = []
    while deq:
        ret.append(sublist(deq))
    return ret

print process([45,78,120,47,58,50,32,34])
#/usr/bin/env python
从集合导入deque
def过程(lst):
"""
给定一个未排序的值列表(例如,对于某些
有效指数i,j,i lst[j])产生
列表的新列表,这样在新列表中,每个子列表*都是*
分类:
对于所有子列表\elem returnval:
断言已排序(子列表)
此外,这是所需的最小子列表集
达到这个条件。
因此,如果输入列表lst实际已排序,则返回
[列表(lst)]。
"""
def子列表(deq):
"""
将物品从deque deq的正面弹出,直到下一个
返回构造的子列表。
"""
sub=[deq.popleft()]
而deq和deq[0]>=sub[-1]:
sub.append(deq.popleft())
返回接头
#在修改lst之前,复制一份lst;使用deque以便
#我们可以便宜地把它取下来。
deq=deque(lst)
输出=[]
ret=[]
而deq:
ret.append(子列表(deq))
回程网
打印过程([45,78120,47,58,50,32,34])
(顺便说一句,在
collections.deque
之前的日子里,我可能只会使用
lst
的反向副本,并在
子列表中使用
lst.pop()
。但这并不是很明显。)

没有循环! 至少,没有明确的循环

import itertools

def process(lst):
    # Guard clause against empty lists
    if len(lst) < 1:
        return lst

    # use a dictionary here to work around closure limitations
    state = { 'prev': lst[0], 'n': 0 }

    def grouper(x):
        if x < state['prev']:
            state['n'] += 1

        state['prev'] = x
        return state['n']

    return [ list(g) for k, g in itertools.groupby(lst, grouper) ]
别开玩笑了,如果你需要在一个列表中对项目进行分组,那就值得注意了。并非总是最简单/最好的答案——但值得一试


编辑:如果您不喜欢闭包,并且更喜欢使用对象来保存状态,这里有一个替代方案:

class process:
    def __call__(self, lst):
        if len(lst) < 1:
            return lst

        self.prev = lst[0]
        self.n = 0

        return [ list(g) for k, g in itertools.groupby(lst, self._grouper) ]

    def _grouper(self, x):
        if x < self.prev:
            self.n += 1

        self.prev = x
        return self.n



data = [45,78,120,47,58,50,32,34]
print (list(process()(data)))
课程流程:
定义呼叫(自我,lst):
如果len(lst)<1:
返回lst
self.prev=lst[0]
self.n=0
return[itertools.groupby(lst,self.\u grouper)中k,g的列表(g)]
def_石斑鱼(self,x):
如果x

EDIT2:因为我更喜欢闭包。。。但是@torek不喜欢字典语法,这里是关于同一解决方案的第三个变体:

import itertools

def process(lst):
    # Guard clause against empty lists
    if len(lst) < 1:
        return lst

    # use an object here to work around closure limitations
    state = type('State', (object,), dict(prev=lst[0], n=0))

    def grouper(x):
        if x < state.prev:
            state.n += 1

        state.prev = x
        return state.n

    return [ list(g) for k, g in itertools.groupby(lst, grouper) ]

data = [45,78,120,47,58,50,32,34]
print (list(process(data)))
导入itertools
def过程(lst):
#防止空列表的防范条款
如果len(lst)<1:
返回lst
#在这里使用一个对象来解决闭包限制
state=type('state',(object,),dict(prev=lst[0],n=0))
def石斑鱼(x):
如果x
为什么不简单地使用一个for循环,而不是使用itertool和所有花哨的东西呢

def list_test(inlist, outlist):
    if not inlist:
        return []
    prev=inlist[0]
    x=[]
    for item in inlist:
        if item >= prev:
            x.append(item)
        else:
            outlist.append(x)
            x=[]
            x.append(item)
        prev=item
    if x:
        outlist.append(x)


in_list=[1,0,1,2,3]
out_list = []
list_test(in_list, out_list)    
print(out_list)


O/p:[[1],[0,1,2,3]]

“我想用双循环从列表中创建元素的子组”双循环是必需的吗?!?为了让事情更清楚,你应该提供一个输入和相应的预期输出的例子。不,这不是一个要求,只是我不知道如何用其他方式来做。好的,我将添加一个输入和输出的示例。实际上,我的问题并不是那么简单,因为为了简化,我写了一个数字,但问题中的每个数字都是:点=浮点(第[0]行),浮点(第[1]行),浮点(第[2]行),第[3]行,第[4]行,第[5]行,为了创建这些子列表,我必须比较不同的点值,以确定它是否属于子列表。我试图提出一个
itertools
方法,但我不喜欢我提出的任何选项。通过使用一个持有状态的类实例,这可能会变得稍微漂亮一些…@torek我在这里使用类(1)并不是为了使用闭包(2)而高兴,因为不必在代码中麻烦实例化对象(我不太喜欢
process()(data)
)。但是使用其中一个是一个品味问题,我想…@torek我已经编辑了答案,添加了一个基于类的等价物。
class process:
    def __call__(self, lst):
        if len(lst) < 1:
            return lst

        self.prev = lst[0]
        self.n = 0

        return [ list(g) for k, g in itertools.groupby(lst, self._grouper) ]

    def _grouper(self, x):
        if x < self.prev:
            self.n += 1

        self.prev = x
        return self.n



data = [45,78,120,47,58,50,32,34]
print (list(process()(data)))
import itertools

def process(lst):
    # Guard clause against empty lists
    if len(lst) < 1:
        return lst

    # use an object here to work around closure limitations
    state = type('State', (object,), dict(prev=lst[0], n=0))

    def grouper(x):
        if x < state.prev:
            state.n += 1

        state.prev = x
        return state.n

    return [ list(g) for k, g in itertools.groupby(lst, grouper) ]

data = [45,78,120,47,58,50,32,34]
print (list(process(data)))
def list_test(inlist, outlist):
    if not inlist:
        return []
    prev=inlist[0]
    x=[]
    for item in inlist:
        if item >= prev:
            x.append(item)
        else:
            outlist.append(x)
            x=[]
            x.append(item)
        prev=item
    if x:
        outlist.append(x)


in_list=[1,0,1,2,3]
out_list = []
list_test(in_list, out_list)    
print(out_list)