chrsmrrtt
chrsmrrtt

Reputation: 197

Python: Use list containing index values to split another list

I have a list of tuples which represent the coordinates of a shape - "points"

I also have a list of index values which identify the starting point for each part of that shape (since a shape can contain one or more 'islands') - "parts"

Currently, to extract a part's points from the points list I do the following:

points = [
    (0, 0), (1, 0), (2, 1), (3, 2), (0, 0),
    (4, 5), (5, 4), (3, 6), (2, 9), (4, 5),
    (2, 2), (3, 2), (6, 4), (4, 4), (8, 6), (4, 3), (2, 2)
]

parts = [0, 5, 10]

for index, part in enumerate(parts):
    start = part

    try:
        end = parts[index + 1]
    except Exception:
        end = len(points)

    print(points[start:end])

However, this does not feel particularly Pythonic to me. To be honest, the use of the exception just feels downright dirty. Can anyone suggest an improved Python v3 methodology for this particular problem?

Upvotes: 2

Views: 1056

Answers (2)

jammon
jammon

Reputation: 3464

for i in range(len(parts)):
    if i==len(parts)-1:
        print(points[parts[i]:])
    else:
        print(points[parts[i]:parts[i+1]])

or:

for i in range(len(parts)-1):
    print(points[parts[i]:parts[i+1]])
print(points[parts[-1]:])

or:

for start, end in zip(parts[:-1], parts[1:]):
    print(points[start:end])
print(points[parts[-1]:])

Upvotes: 1

Irfy
Irfy

Reputation: 9587

You want to do this:

parts = [0, 5, 10, len(points)]
start_end_pairs = zip(parts[:-1], parts[1:])

for start, end in start_end_pairs:
    print(points[start:end])

Explanation

Your parts already contains the starting indices, so you only need to take the contents of that array to calculate what you want.

From [0, 5, 10], you need to take (0, 5) for the first part, (5, 10) for the second, and (10, len(points)) for the third part. The process of creating these pairs to use in the print-loop can easily be implemented with zip. I zip the two arrays:

[0, 5, 10]
[5, 10, len(points)]

to produce

[(0, 5), (5, 10), (10, len(points))]

which is exactly what you need.

Upvotes: 6

Related Questions