dispepsi
dispepsi

Reputation: 270

python: indexing/pagination of two paired lists

Let's say I have two lists like this that must be represented as pairs:

cities = ['San Francisco', 'New York', 'Seattle', 'Portland', ]
states = ['CA', 'NY', 'WA', 'OR']

And I have a function like this:

def list(page):
    return "{0} -> {1} \n {2} -> {3} \n {4} -> {5} \n {6} -> {7}".format(keys[0], values[0], keys[1], values[1], keys[2], values[2], keys[3], values[3])

I want to be able to use an integer (here, page) to index these pairs display them three at a time. So let's say I have ten pairs of cities and states, 1 it would display the first three, 2 the second three, etc.

Pseudo-ly, I imagine it would look like this:

def list(page):
    for page < 2:
        return first triplet
    for page < 3:
        return second triplet
    # etc.

But I think there could be a better way, and I'm wondering what that might look like.

Upvotes: 1

Views: 371

Answers (4)

Jason Child
Jason Child

Reputation: 11

def foo(a,b,n):
return "".join(map(lambda x,y:"{0} -> {1}\n".format(x,y),a[n*3:(n*3)+3],b[n*3:(n*3)+3]))

This shouldn't try to index past the array bounds and would allow you to return a page of 1-2 entries without explicit bounds checking or exception handling. You may want to ensure you have arrays of equal length, otherwise you get some combo of

None -> StateN

Upvotes: 1

TigerhawkT3
TigerhawkT3

Reputation: 49330

Setup:

cities = ['San Francisco', 'New York', 'Seattle', 'Portland', ]
states = ['CA', 'NY', 'WA', 'OR']

A function to split a generator into chunks:

from itertools import islice

def chunks(iterable, size=10):
    iterator = iter(iterable)
    for first in iterator:    # stops when iterator is depleted
        def chunk():          # construct generator for next chunk
            yield first       # yield element from for loop
            for more in islice(iterator, size - 1):
                yield more    # yield more elements from the iterator
        yield chunk()         # in outer generator, yield next chunk

This gives you a generator that yields chunks of a given size. To put it together:

>>> for chunk in chunks(zip(cities, states)):
...     for piece in chunk:
...             print('{}, {}'.format(*piece))
...
San Francisco, CA
New York, NY
Seattle, WA
Portland, OR

You can also just turn this into a list of chunks as follows:

>>> places = [list(chunk) for chunk in chunks(zip(cities, states), 3)]
>>> places[0]
[('San Francisco', 'CA'), ('New York', 'NY'), ('Seattle', 'WA')]

And print a given chunk:

>>> print(*('{}, {}'.format(*place) for place in places[0]), sep='\n')
San Francisco, CA
New York, NY
Seattle, WA

Upvotes: 2

dirn
dirn

Reputation: 20749

You should use islice and zip.

from itertools import islice

def list_(page):
    return islice(zip(cities, states), (page - 1) * 3, page * 3)

Note, if you're using a version of Python less than 3 you'll want to use izip, found in itertools.

Upvotes: 1

Loocid
Loocid

Reputation: 6451

How about something like this:

def list(page):
    page -= 1
    return "{0} -> {1} \n {2} -> {3} \n {4} -> {5}".format(keys[0 + 3*page], values[0 + 3*page], keys[1 + 3*page], values[1 + 3*page], keys[2 + 3*page], values[2 + 3*page], keys[3 + 3*page], values[3 + 3*page])

Not the prettiest code but this will make it so if you call list(2) it will print out the 2nd group of three pairs. Calling list(5) will print the 5th etc.

Note that this code doesn't have error checking so if you call page 4 but only have 10 states you will get an index error.

Upvotes: 0

Related Questions