问题描述:

Sorry for creating this question but I have been stuck on this question for a while.

Basically I'm trying to take a list:

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

And subset this list into a list of list that display positive/negative movements (or trends)

The end result is to have:

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

Basically I have been using nested while functions to append a positive movement to the subset, and when the condition is not met, the subset is appended to subset_list and then evaluates if there is a negative movement.

I keep getting an `IndexError`

, and so far `subset_list`

only contains `[[1, 2]]`

Here is my code:

`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

Thanks!

-Jake

This is what I came up with. It is close to what you have but a little easier to read. I avoid having to increment the index counter `i`

as much which is *probably* where you went wrong.

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

Here is a way to re-write this:

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

In python, one tends not to use the actual indexes in a list very often. Try a for-loop instead, plus a check to see whether the trend changed or not (this treats zero as a distinct trend from positive or negative - you can pretty simply change `same_direction`

to group it one way or the other):

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

If change in trends always go through the sign change, you can "group" items based on a sign using `itertools.groupby()`

:

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

We are using `_`

as a variable name for a "throw-away" variable since we don't need the grouping key in this case.

Here is my solution:

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

Unfortunately, I only have python 3 on my system so my answer is in python 3.