Vivek Harikrishnan
Vivek Harikrishnan

Reputation: 866

Finding combinations pairs of list items forward

I have a input list,

n = [0, 6, 12, 18, 24, 30, 36, 42, 48] 
# Here, the list is multiples of 6 
# but need not always be, could be of different numbers or unrelated.

Now I would like to generate pair of numbers from the list so the output is,

output = [(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)]

I have below snippet to get it done.

zip([(i+1) for i in n[:-1]], n[1:])

Just out of curious, I would like to know the other approaches than what I have!

Upvotes: 2

Views: 302

Answers (5)

user9158931
user9158931

Reputation:

Are you looking for something like this ?

final_list=[]
n = [0, 6, 12, 18, 24, 30, 36, 42, 48]
for i in range(0,len(n),1):
    chuck=n[i:i+2]
    if len(chuck)<2:
        pass
    else:
        final_list.append((chuck[0]+1,chuck[1]))
print(final_list)

output:

[(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)]

You can also do in one line:

n = [0, 6, 12, 18, 24, 30, 36, 42, 48]
print([(n[i:i+2][0]+1,n[i:i+2][1]) for i in range(0,len(n),1) if len(n[i:i+2])==2])

Upvotes: 0

Hamed Baziyad
Hamed Baziyad

Reputation: 2019

n1=range(0,49)
n=n1[1::6]
x1=range(1,44)
x=x1[::6]
print (zip(x,n))

Upvotes: 0

cs95
cs95

Reputation: 402483

What you have right now is pretty good (in my books). Although, you could substitute the n[:-1] with n, because zip performs a "shortest possible zipping" - zips upto the shorter of the two lists -

>>> list(zip([1, 2, 3], [4, 5]))
[(1, 4), (2, 5)]

So, you could rewrite your expression as -

list(zip([(i+1) for i in n], n[1:]))

For conciseness. Drop the list(..) for python 2.

An alternative (suggested by RoadRunner), would be to bring the list comprehension out, and the zip in -

>>> [(x + 1, y) for x, y in zip(n, n[1:])]
[(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)]

Or, you can get rid of zip completely (as suggested by splash58), by using positional based indexing -

>>> [(n[i] + 1, n[i + 1]) for i in range(len(n) - 1)]
[(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)]

Another way to do this is using the functional programming paradigm, with map -

>>> list(zip(map(lambda x: x + 1, n), n[1:]))
[(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)]

Which does the same thing your list comp does, but probably slower!


And finally, if you use pandas (my favourite library), then you can leverage the IntervalIndex API -

>>> pd.IntervalIndex.from_breaks(n, closed='right')
IntervalIndex([(0, 6], (6, 12], (12, 18], (18, 24], (24, 30], (30, 36], (36, 42], (42, 48]]
              closed='right',
              dtype='interval[int64]')

Upvotes: 5

RoadRunner
RoadRunner

Reputation: 26315

Adding to @cᴏʟᴅsᴘᴇᴇᴅ's recommendation of the functional programming paradigm, you could also use map() without zip() to do this:

n = [0, 6, 12, 18, 24, 30, 36, 42, 48] 

result = list(map(lambda x, y: (x + 1, y), n, n[1:]))

print(result)
# [(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)

Upvotes: 3

Anton vBR
Anton vBR

Reputation: 18916

Another one as numpy accepts integer addition:

import numpy as np

n = [0, 6, 12, 18, 24, 30, 36, 42, 48] 
a = np.array(n)
output = list(zip(a+1,a[1:]))

print(output)

Returns:

[(1, 6), (7, 12), (13, 18), (19, 24), (25, 30), (31, 36), (37, 42), (43, 48)]

Upvotes: 3

Related Questions