2

I have a set of data in the form:

X1 = [(1,1),(3,1),(5,0),(3,0),(2,1)]

I can't figure out how to group them such that:

X2 = [[(1,1),(3,1)],[(5,0),(3,0)],[(2,1)]]

i.e. they are grouped in a consecutive fashion by the second value in each tuple.

I know it's something with this:

http://docs.python.org/2/library/itertools.html#itertools.groupby

ekad
  • 14,436
  • 26
  • 44
  • 46
user3394391
  • 487
  • 6
  • 15
  • why would you want to use itertools when there are easier ways? – Ol' Reliable Mar 16 '14 at 23:55
  • 1
    @Ol'Reliable: Because your "easier way" does something different. What if the data is `[(0, 1), (1, 1), (2, 1), (0, 0), (0, 2)]`? – user2357112 Mar 16 '14 at 23:56
  • what should the output be? – Ol' Reliable Mar 17 '14 at 00:05
  • `[[(0, 1), (1, 1), (2, 1)], [(0, 0)], [(0, 2)]]` – user2357112 Mar 17 '14 at 00:05
  • ok ok, im sorry, i didn't quite fully understand the problem – Ol' Reliable Mar 17 '14 at 00:14
  • No need to apologise man! Grouping is dictated by the second value in each tuple. eg. for X1 ignoring the first values these are (a,1),(b,1),(c,0),(d,0),(e,1) Consecutive values that are equal are grouped: ((a,1),(b,1))((c,0),(d,0)),(e1)) Of course the second values could be anything... but they will always be grouped based on equal value and consecutive positioning. – user3394391 Mar 17 '14 at 00:36

3 Answers3

5
from itertools import groupby
from operator import itemgetter
X2 = [list(group) for key, group in groupby(X1, itemgetter(1))]

Pass a key function to groupby that fetches the second item of each tuple, so groupby groups the tuples by their second items.

user2357112
  • 260,549
  • 28
  • 431
  • 505
0
from itertools import groupby, imap
from operator  import itemgetter

X1 = [(1,1),(3,1),(5,0),(3,0),(2,1)]
print map(list, imap(itemgetter(1), groupby(X1, itemgetter(1))))
# -> [[(1, 1), (3, 1)], [(5, 0), (3, 0)], [(2, 1)]]
jfs
  • 399,953
  • 195
  • 994
  • 1,670
-2
x = [(1,1),(3,1),(5,0),(3,0),(2,1)]
y = [x[n:n+2] for n in range(0, len(x), 2)]
print(y)
Ol' Reliable
  • 570
  • 1
  • 8
  • 19