在列表中找到单调序列? [英] Find monotonic sequences in a list?

查看:151
本文介绍了在列表中找到单调序列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Python中的新成员,但基本上我想从列表中创建具有双重循环的元素的子组,因此我要比较第一个元素和下一个元素,找出是否可以创建这些子列表,否则我将打破内部的循环,我想继续最后一个元素,但在主循环:
$ b

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



比较5和7是小的吗?是的,所以包含在新列表中,并用内部继续8,小于5?是的,所以包括在新列表中,但是当与4比较,我打破循环,所以我想继续与这4个下一个,在这种情况下,与11 ... ... $ / b
$ b

 对于xrange(len(path))中的m:
对于xrange(m + 1,len(path))中的i:
if path [i]> path [m]):
newlist.append(path [i])

else:
break

m = m +

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



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



由于要比较整个列表的子组,所以要做一个双循环,换句话说就是当45比下一个小时才添加到新列表中,如果不是下一个比较在这种情况下是47并开始与58比较。 没有循环!
至少,不显式循环...



$ p $ import itertools

def process(lst):
#针对空列表的Guard子句
如果len(lst)< 1:
return lst

#在这里使用一个字典来解决关闭限制
state = {'prev':lst [0],'n':0}

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

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

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

用法(与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]]

开玩笑的话,如果你需要在 项。 org / 2 / library / itertools.html#itertools.groupbyrel =noreferrer> itertools.groupby 值得一点关注。并不总是最简单/最好的答案 - 但值得一试... ...

$ hr
$ b

编辑:

/ strong>如果您不喜欢闭包 - 并且更喜欢使用对象来保存状态,则可以使用以下方法:

  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
返回self.n



数据= [45,78,120,47,58,50,32,34]
print(list(process()(data)))
因为我喜欢封闭...但@torek不喜欢
> dictionary 语法,这里是围绕相同解决方案的第三个变体:

  import itertools 

def process(lst):
#针对空列表的保护子句
如果len(lst)< 1:
return lst

#在这里使用一个对象来解决关闭限制
state = type('State',(object,),dict(prev = lst [0 ],n = 0))

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

state.prev = x
return state.n

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

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


I'm new in Python but basically I want to create sub-groups of element from the list with a double loop, therefore I gonna compare the first element with the next to figure out if I can create these sublist, otherwise I will break the loop inside and I want continue with the last element but in the main loop:

Example: 5,7,8,4,11

Compare 5 with 7, is minor? yes so include in the newlist and with the inside for continue with the next 8, is minor than 5? yes, so include in newlist, but when compare with 4, I break the loop so I want continue in m with these 4 to start with the next, in this case with 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

Thanks for suggestions or other ideas to achieve it!

P.S. Some input will be: input: [45,78,120,47,58,50,32,34] output: [45,78,120],[47,58],50,[32,34]

The idea why i want make a double loops due to to compare sub groups of the full list,in other way is while 45 is minor than the next one just add in the new list, if not take the next to compare in this case will be 47 and start to compare with 58.

解决方案

No loop! Well at least, no explicit looping...

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

Usage (work both with 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]]

Joke apart, if you need to group items in a list itertools.groupby deserves a little bit of attention. Not always the easiest/best answer -- but worth to make a try...


EDIT: If you don't like closures -- and prefer using an object to hold the state, here is an alternative:

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


EDIT2: Since I prefer closures ... but @torek don't like the dictionary syntax, here a third variation around the same solution:

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

这篇关于在列表中找到单调序列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆