Python 在列表中查找单调序列?
我是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)):
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)