25

I have a list of small integers, say:

[1, 2, 3, 4, 5, 6]

I wish to collect the sequential pairs and return a new list containing tuples created from those pairs, i.e.:

[(1, 2), (3, 4), (5, 6)]

I know there must be a really simple way to do this, but can't quite work it out.

Thanks

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • 5
    Is this homework? If so, please use the [homework] tag. – S.Lott Jan 10 '11 at 13:00
  • 2
    possible duplicate of [Pairs from single list](http://stackoverflow.com/questions/4628290/pairs-from-single-list) and many others. – Jochen Ritzel Jan 10 '11 at 13:05
  • @S.Lott, why could it be a homework? Does it look like from your experience? – Senthil Kumaran Jan 10 '11 at 13:06
  • Not homework, personal interest – TartanLlama Jan 10 '11 at 13:09
  • @S.Lott it's for carrying out aside processing on pre-existing data passed from a different program. – TartanLlama Jan 10 '11 at 13:14
  • @TartanLlama: "pre-existing data passed from a different program"? Perhaps you should ask your **real** question. It sounds like the other program may have a design problem or the input parser may have a small design problem. Creating a flat list like this and reformatting it into pairs is less than ideal. There may be a way to avoid all of this. – S.Lott Jan 10 '11 at 13:16
  • @S.Lott: Obviously I've got changes to make there, this was more out of interest because I realized that I didn't know how to carry out this task. – TartanLlama Jan 10 '11 at 13:18
  • n-duplicated: just in a quick search: http://stackoverflow.com/questions/4501636, http://stackoverflow.com/questions/312443, http://stackoverflow.com/questions/4170295, http://stackoverflow.com/questions/434287 – tokland Jan 10 '11 at 13:18
  • 2
    I'm not sure what "impractical" even means in this situation. Software challenges are often the result of data being in impractical shapes. Consider an old way of organizing data that must change due to new business requirements. A judgement like "impractical" is full of assumptions and speculation based in smoke. – jaydel Jan 10 '11 at 13:22
  • @jaydel: Not really. The input can be always be built into pairs as it's being read. Reading as a flat list and restructuring the list can always be avoided. It isn't "speculation". It's a matter of changing the software design to assemble the desired data structure straight away. If it can be assembled in two steps, it can be refactored so the assembly happens in one step. – S.Lott Jan 10 '11 at 14:04
  • @S.Lott: what I'm saying is that at one point having that input as a list, and also still needing it as that list is a situation that might have been made necessary due to business logic and requirements. In a new release an instance where it's required to be in the new format might now exist and have the list already in hand. All I'm saying is that the practicalness or impracticalness is defined by business requirements and the behavior of the program. My opinion is that you don't have enough information to make that call. I don't mean this as an attack. You just don't have the full context. – jaydel Jan 10 '11 at 14:42
  • @jaydel: If it can be assembled in two steps, it can be refactored so the assembly happens in one step. It's not a matter of "business requirements". It's a matter of design. Any inefficient two-step process can be refactored to a more efficient one-step process. I understand that the flat list may have some value, but the comment "pre-existing data passed from a different program" seems to indicate that the flat list had no other purpose. Yes, I could be wrong. Fixing the design, however, could be more efficient than the answers to this question. – S.Lott Jan 10 '11 at 14:46
  • I'll buy that. I think the thing that originally tripped me up was the hard assertion that it was impractical. I mentally added 'seems' or even 'is probably' before it and felt much better. – jaydel Jan 10 '11 at 16:10
  • @jaydel: Given the comment ("pre-existing data passed from a different program") it sure seems like the design is utterly impractical. There is still a real possibility that the comment is incorrect or incomplete. – S.Lott Jan 10 '11 at 18:25

3 Answers3

44

Well there is one very easy, but somewhat fragile way, zip it with sliced versions of itself.

zipped = zip(mylist[0::2], mylist[1::2])

In case you didn't know, the last slice parameter is the "step". So we select every second item in the list starting from zero (1, 3, 5). Then we do the same but starting from one (2, 4, 6) and make tuples out of them with zip.

Skurmedel
  • 21,515
  • 5
  • 53
  • 66
  • 5
    An odd number of elements may have surprising results. Also, a zero-length list will behave badly. – S.Lott Jan 10 '11 at 13:17
  • 1
    the solution to fragility can be this small tweak (if you don't mind having empty string when elements are odd) `if len(mylist)%2 !=0: mylist.append('') ; zip(mylist[0::2], mylist[1::2])` – Aseem Yadav May 05 '19 at 12:37
  • 1
    `zipped = itertools.zip_longest(mylist[0::2], mylist[1::2])` to pad odd length lists, default `fillvalue=None` – Steven Than Apr 19 '20 at 04:41
10

Apart from the above answers, you also need to know the simplest of way too (if you hadn't known already)

l = [1, 2, 3, 4, 5, 6]
o = [(l[i],l[i+1]) for i in range(0,len(l),2)]
Senthil Kumaran
  • 54,681
  • 14
  • 94
  • 131
6

Straight from the Python documentation of the itertools module:

from itertools import tee, izip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

l = [1, 2, 3, 4, 5, 6]
for pair in pairwise(l):
    print pair
Jim Brissom
  • 31,821
  • 4
  • 39
  • 33