import itertools
l = [38, 1200, 1200, 306, 306, 391, 391, 82, 82, 35, 35, 902, 902, 955, 955, 13]
for x, v in itertools.groupby(l):
# `v` is an iterator that yields all subsequent elements
# that have the same value
# `x` is that value
print list(v)
import itertools
def split_sublists(input_list):
sublist = []
for val, l in itertools.groupby(input_list):
l = list(l)
if not sublist or len(l) == 2:
sublist += l
else:
sublist += l
yield sublist
sublist = []
yield sublist
input_list = [1,4,4,5,5,8,8,10,10,25,25,70,70,90,90,100,2,3,3,4,4,5,5,8,8,9,20,21,21,22,23]
for sublist in split_sublists(input_list):
print sublist
x = [38, 1200, 1200, 306, 306, 391, 391, 82, 82, 35, 35, 902, 902, 955, 955, 13, 955, 847, 847, 835, 83, 5698, 698, 777, 777, 896, 896, 923, 923, 940, 940, 569, 569, 53, 53, 411]
def weird_split(alist):
sublist = []
for i, n in enumerate(alist[:-1]):
sublist.append(n)
# make sure we only create a new list if the current one is not empty
if len(sublist) > 1 and n != alist[i-1] and n != alist[i+1]:
yield sublist
sublist = []
# always add the last element
sublist.append(alist[-1])
yield sublist
for sublist in weird_split(x):
print sublist
def group(l,skip=0):
prevind = 0
currind = skip+1
for val in l[currind::2]:
if val != l[currind-1]:
if currind-prevind-1 > 1: yield l[prevind:currind-1]
prevind = currind-1
currind += 2
if prevind != currind:
yield l[prevind:currind]
val is 1, at index 1. comparing to value at 0 i.e 1
make currind the index of last element of the next pair
val is 3, at index 3. comparing to value at 2 i.e 3
make currind the index of last element of the next pair
val is 5, at index 5. comparing to value at 4 i.e 2
not equal so get slice between 0,4
[1, 1, 3, 3]
make currind the index of last element of the next pair #happens after the for loop
[2, 5]
5条答案
按热度按时间mfpqipee1#
为了回答您的问题:
我有[...]一个列表。每当后面的数字不等于它前面的值时,我想把它分成单独的列表。
看看
itertools.groupby
。示例:
输出为:
显然这就是你想要的?
至于你的模式,这里有一些生成器函数,它至少能为给定的输入产生你所期望的输出:
输出:
afdcj2ne2#
numpy 版本:
你的新案子是一样的:
以
x
作为列表开始:如果
x
是numpy数组:对于较大的系统,你可以期待numpy比python有更好的性能。
luaexgnf3#
下面是我的丑陋的解决方案:
并且输出:
cwdobuhd4#
首先,您还没有定义
[1, 0, 0, 1, 0, 0, 1]
的行为,因此这会将其拆分为[1, 0, 0, 1]
、[0, 0]
和[1]
。其次,有很多极端情况需要正确处理,所以它比你想象的要长,如果它直接把东西放进列表,它也会缩短,但是生成器是个好东西,所以我确保不那样做。
首先,使用完整的迭代器接口,而不是
yield
快捷方式,因为它允许更好地共享外部和内部迭代器之间的状态,而无需在每次迭代时生成新的subsection
生成器。带有yield
s的嵌套def
可能能够在更少的空间内实现这一点,但在这种情况下,我认为冗长是可以接受的。因此,设置:
我们需要定义一个子迭代器,它在找到一个不匹配的对之前产生,因为结尾将从迭代器中移除,我们需要在下一次调用
_subsection
时将其yield
,所以将其存储在_cache
中。__iter__
应为可迭代项返回self
:__next__
返回一个子段,除非完成。注意,如果要使行为可靠,则完成该子段是很重要的。一些测试:
一些时间来证明这并不是完全没有意义的:
结果:
虽然差别不大,但还是快多了。
sdnqo3pr5#
对于您定义的列表,当使用
skip=1
调用时返回下面是一个简单的示例列表
[1,1,3,3,2,5]
:skip
是该函数的可选参数的原因是,在您的示例中,尽管 * 38 * 不等于 * 1200 *,但它仍被包含在内。如果这是一个错误,则只需删除skip并将currind
初始设置为等于1
。在一个列表
[a,b,c,d,e,...]
中,我们想连续比较两个元素,即a == b
,c == d
,然后当比较没有返回True
时,捕获所有前面的元素(不包括那些已经捕获的)。为此,我们需要跟踪上次捕获发生的位置,其初始值为0
(即没有捕获)。然后我们检查每一对,通过遍历列表中从currind
开始的每个 * 第二 * 元素(不跳过元素时)为1。然后将从l[currind::2]
获得的值与它之前的值l[currind-1]
进行比较。currind
是currind
'中每个 * 第二 * 个元素的索引初始值(默认为1
)。如果值 * 不 * 匹配,那么我们需要执行捕获,但只有当结果捕获将包含一个项!因此currind-prevind-1
〉1(因为列表分片的长度为-1,所以它需要为2或更大才能提取至少1个元素)。l[prevind:currind-1]
执行此捕获,从上次不匹配的比较的索引开始(或默认为0
),直到每个比较对a,b
或c,d
等中的第一个值之前的元素***。然后prevind
被设置为currind-1
,即捕获的最后一个元素的索引。然后,我们将currind
递增2,以到达下一个val
的索引,最后,如果有一个对剩余,我们提取它。因此,对于
[1,1,3,3,2,5]
: