Pergunta

Let's say I have a list of integers:

list = [1,2,3,5,6,7,10,11,12]

And I'd like to divide the list in to three separate lists, with the split occurring between consecutive integers with a difference >=2, which would give me

list1 = [1, 2, 3]
list2 = [5, 6, 7]
list3 = [10, 11, 12]

Is there a straightforward way to do this in Python? I would like to do this in order to analyze data from a psychology experiment, where I have a list of timestamped response and want to cluster responses based on how far apart they are

Foi útil?

Solução

Take a look at this StackOverflow question. The answers there show you how to divide a list into sublists of consecutive integers.

From the accepted answer there:

>>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
>>> for k, g in groupby(enumerate(data), lambda (i,x):i-x):
...     print map(itemgetter(1), g)
...
[1]
[4, 5, 6]
[10]
[15, 16, 17, 18]
[22]
[25, 26, 27, 28]

The answer doesn't offer any explanation of what's going on here, so I'll explain. First, it assumes that data is sorted in ascending order. Enumerating data then gives a list of index, value pairs. It then uses the index minus the value as a key for grouping the items. Take a look at what this does for your list:

>>> myList = [1,2,3,5,6,7,10,11,12]
>>> [i - x for i, x in enumerate(myList)]
[-1, -1, -1, -2, -2, -2, -4, -4, -4]

As you can see, consecutive values end up having the same grouping key. This is because

if data[i] + 1 == data[i+1]:

then data[i] - i == data[i] + 1 - 1 - i == data[i+1] - (i + 1)

FYI, groupby comes from itertools and itemgetter comes from operator. So add these lines to your imports:

from itertools import groupby
from operator import itemgetter

Just be aware that this solution will only work if data is sorted and does not contain any duplicates. Of course, it's fairly straightforward to turn a list into a sorted set:

>>> myList = [1, 1, 3, 5, 6, 4, 10, 12, 11, 1, 2]
>>> myList = list(sorted(set(myList)))
>>> print myList
[1, 2, 3, 4, 5, 6, 10, 11, 12]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top