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

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

问题描述

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

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

5 和 7 比较,是次要的吗?是的,所以包含在新列表中,并在里面继续下一个 8,是否小于 5?是的,所以包含在新列表中,但是当与 4 比较时,我打破了循环,所以我想在 m 中继续这 4 个以从下一个开始,在这种情况下为 11 ...

 for m in xrange(len(path)):对于 xrange(m+1,len(path)) 中的 i:如果(路径 [i] > 路径 [m]):newlist.append(path[i])别的:休息m=m+i

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

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

由于比较完整列表的子组,我想要进行双循环的想法,换句话说,虽然 45 比下一个小,只需添加到新列表中,如果不取下一个进行比较这个案例将是 47 并开始与 58 进行比较.

解决方案

无循环!至少,没有显式循环......

import itertools定义进程(lst):# 防止空列表的子句如果 len(lst) <1:返回列表# 在这里使用字典来解决闭包限制状态 = { 'prev': lst[0], 'n': 0 }定义石斑鱼(x):如果 x <状态['上一个']:状态['n'] += 1状态['上一个'] = x返回状态['n']返回 [ list(g) for k, g in itertools.groupby(lst, grouper) ]

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

<预><代码>>>>数据 = [45,78,120,47,58,50,32,34]>>>打印(列表(进程(数据)))[[45, 78, 120], [47, 58], [50], [32, 34]]

开个玩笑,如果您需要分组 列表中的项目itertools.groupby 值得关注.并不总是最简单/最好的答案——但值得一试......

<小时>

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

课程流程:def __call__(self, lst):如果 len(lst) <1:返回列表self.prev = lst[0]self.n = 0返回 [ list(g) for k, g in itertools.groupby(lst, self._grouper) ]def _grouper(self, x):如果 x 

<小时>

因为我更喜欢闭包......但@torek 不喜欢字典 语法,这里有关于相同解决方案的第三种变体:

import itertools定义进程(lst):# 防止空列表的子句如果 len(lst) <1:返回列表# 在这里使用一个对象来解决闭包限制state = type('State', (object,), dict(prev=lst[0], n=0))定义石斑鱼(x):如果 x <状态.prev:状态.n += 1状态.prev = x返回状态.n返回 [ list(g) for k, g in itertools.groupby(lst, grouper) ]数据 = [45,78,120,47,58,50,32,34]打印(列表(进程(数据)))

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天全站免登陆