在列表中查找单调序列?

tao*_*ico 2 python iteration for-loop

我是Python的新手,但基本上我想用一个双循环从列表中创建元素的子组,因此我将比较第一个元素和下一个元素,以确定我是否可以创建这些子列表,否则我将打破循环里面,我想继续最后一个元素,但在主循环中:

例: 5,7,8,4,11

比较5和7,是次要的?是的所以包括在新列表中并且内部继续下一个8,是否小于5?是的,所以包括在新列表中,但是当与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
Run Code Online (Sandbox Code Playgroud)

感谢您的建议或其他想法来实现它!

PS一些输入将是:输入:[45,78,120,47,58,50,32,34] 输出:[45,78,120],[47,58],50,[32,34]

这个想法为什么我要做一个双循环,因为要比较完整列表的子组,换句话说是45是小于下一个只是在新列表中添加,如果没有采取下一个比较在这种情况下将是47并开始与58比较.

Syl*_*oux 5

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

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) ]
Run Code Online (Sandbox Code Playgroud)

用法(适用于Python 2和Python 3):

>>> data = [45,78,120,47,58,50,32,34]
>>> print (list(process(data)))
[[45, 78, 120], [47, 58], [50], [32, 34]]
Run Code Online (Sandbox Code Playgroud)

笑话,如果你需要在列表中分组项目itertools.groupby值得一点关注.并不总是最简单/最好的答案 - 但值得尝试...


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

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)))
Run Code Online (Sandbox Code Playgroud)

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)))
Run Code Online (Sandbox Code Playgroud)