Steven Lu - 9 months ago 71

Python Question

I've got a structure of the form:

`>>> items`

[([[0, 1], [2, 20]], 'zz', ''), ([[1, 3], [5, 29], [50, 500]], 'a', 'b')]

The first item in each tuple is a list of ranges, and I want to make a generator that provides me the ranges in ascending order based on the starting index.

Since the range-lists are already sorted by their starting index this operation is simple: it is just a sorted merge. I'm hoping to do it with good computational efficiency, so I'm thinking that one good way to implicitly track the state of my merge is to simply pop the front off of the list of the tuple which has the smallest starting index in its range list.

I can use

`min()`

`[0, 1]`

I have this:

`[ min (items[i][0]) for i in range(len(items)) ]`

which gives me the first item in each list, which I can then

`min()`

`pop()`

To summarize: Want to build generator that returns for me:

`([0,1], 'zz', '')`

([1,3], 'a', 'b')

([2,20], 'zz', '')

([5,29], 'a', 'b')

([50,500], 'a', 'b')

Or even more efficiently, I only need this data:

`[0, 1, 0, 1, 1]`

(the indices of the tuples i want to take the front item of)

Answer

This works:

```
by_index = ([sub_index, list_index] for list_index, list_item in
enumerate(items) for sub_index in list_item[0])
[item[1] for item in sorted(by_index)]
```

Gives:

```
[0, 1, 0, 1, 1]
```

In detail. The generator:

```
by_index = ([sub_index, list_index] for list_index, list_item in
enumerate(items) for sub_index in list_item[0])
list(by_index)
[[[0, 1], 0], [[2, 20], 0], [[1, 3], 1], [[5, 29], 1], [[50, 500], 1]]
```

So the only thing needed is sorting and getting only the desired index:

```
[item[1] for item in sorted(by_index)]
```

Source (Stackoverflow)