将 python 列表子集化为 positive/negative movements/trends

Subsetting python list into positive/negative movements/trends

很抱歉提出这个问题,但我已经在这个问题上停留了一段时间。

基本上我正在尝试列出一个列表:

numbers=[1, 2, -1, -2, 4, 5]

并将此列表子集化为显示 positive/negative 移动(或趋势)的列表列表

最后的结果是:

subset_list = [[1, 2], [-1, -2], [4, 5]] 

基本上我一直在使用嵌套的while函数给子集追加正向运动,当条件不满足时,子集追加到subset_list,然后判断是否有负向运动。

我一直收到 IndexError,到目前为止 subset_list 只包含 [[1, 2]]

这是我的代码:

numbers = [1,2,-1,-2,4,5]

subset = []
subset_list = []
subset.append(numbers[0])

i = 1
while i < (len(numbers)):
    if numbers[i] <= numbers[i+1]:
        subset.append(numbers[i])
        i+= 1
        while subset[-1] <= numbers[i] or numbers[i] <= numbers[i+1]:
            subset.append(numbers[i])
            i += 1
        subset_list.append(subset)
        subset = []
        i += 1
    if numbers[i] > numbers[i+1]:
        subset.append(numbers[i])
        i+= 1
        while subset[-1] <= numbers[i] or numbers[i] <= numbers[i+1]:
            subset.append(numbers[i])
            i+= 1
        subset_list.append(subset)
        subset = []
        i += 1

谢谢!

-杰克

如果趋势变化总是通过符号变化,您可以 "group" 基于符号的项目使用 itertools.groupby():

>>> from itertools import groupby
>>>
>>> [list(v) for _, v in groupby(numbers, lambda x: x < 0)]
[[1, 2], [-1, -2], [4, 5]]

我们使用 _ as a variable name 作为 "throw-away" 变量,因为在这种情况下我们不需要分组键。

在python中,人们往往不经常使用列表中的实际索引。尝试使用 for 循环,并检查趋势是否发生变化(这将零视为与正面或负面截然不同的趋势 - 您可以非常简单地更改 same_direction 以一种或另一种方式对其进行分组) :

def same_direction(num1, num2):
    # both numbers are positive, both are negative, or both are zero
    return ((num1 > 0 and num2 > 0) or
            (num1 < 0 and num2 < 0) or
            (num1 == num2))

numbers = [1, 2, -1, -2, 4, 5]
result = [[]] #list with one sublist ready
last_number = 0
for num in numbers:
    if same_direction(num, last_direction):
        # No need for a new sublist, put new number in last sublist
        result[-1].append(num)
    else:
        # trend changed, new sublist and put the number in it
        result.append([num])

这是我想到的。它与您所拥有的很接近,但更容易阅读。我避免将索引计数器 i 增加到 可能 你出错的地方。

n= [1,2,-1,-2,4,5]
out=[]
i=1
tmp=[n[0]]
while i < len(n):
        if n[i] >= 0 and tmp[-1] >= 0:
                tmp.append(n[i])
        elif n[i] < 0 and tmp[-1] < 0:
                tmp.append(n[i])
        else:
                out.append(tmp)
                tmp = [n[i]]
        i = i + 1
if len(tmp) > 0: # typo fix was > 1
        out.append(tmp)

print(out)

这里有一个重写的方法:


numbers=[1,2,-1,-2,4,5] 


direction = True  # positive or negative
prevdirection = True
res = [[numbers[0]]]

for previtem, item in zip(numbers[:-1], numbers[1:]):
    direction = True if item - previtem > 0 else False
    if direction != prevdirection:
        res.append([])
    prevdirection = direction
    res[-1].append(item)

print(res)    

这是我的解决方案:

numbers = [1,2,-1,-2,4,5, 3, 2]

subset = []
subset_list = []
subset.append(numbers[0])


forward = 1

for i in range(0, len(numbers) - 1):
    if ( forward == 1 ):
        if numbers[i] <= numbers[i+1]:
            subset.append(numbers[i+1])
        else:
            subset_list.append(subset)
            subset = []
            subset.append(numbers[i+1])
            forward = 0
    else:
        if numbers[i] >= numbers[i+1]:
            subset.append(numbers[i+1])
        else:
            subset_list.append(subset)
            subset = []
            subset.append(numbers[i+1])
            forward = 1

subset_list.append(subset)

print(*subset)          
print(*subset_list)

不幸的是,我的系统上只有 python 3,所以我的答案是 python 3.