Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python:[[1,2],[3,4],[5,6],[7,8]] transform into [[1],[2,3],[4,5],[6,7],[8]] and vice versa

my current solution-pointers would be

  • ether via a iterator class which yields the new assembled inner lists
  • or via a iter function which yields the new assembled inner lists

is there another, better way to solve this challenge?

Edit

@Glenn: good objection. I wasn't thinking of that because I experienced lists not ordered in the manner I thought.

@THC4k: thank you for your solution. I learned chain.from_iterable

@Mike DeSimone: Hmm tested your solution but something went wrong maybe I missed something yet,...

@Jamie and Odomontois: Thank you for pointing out to be more detailed

my goal

I am forging a small algorithm which transforms a list of tasks – pairs/tuples: (start,stop) – to a simplified list of task, where the overlapping tasks merged together.

One exeption: my algorithm fails when one event is completely overlapped by another (s1 s2 e2 e1 )

Detailed:

  • I've a list 'taskList' with pairs (lesson learned - tuples :).
  • each tuple consists of 2 datetimeobjects: start and end of a task.
  • important: the chronology of 'taskList' where the order is determined by start because tasks may overlapp
  • 'taskList' consists several days, therefore datetime objects

Example, just string representation of time for readability

taskList = [(9:00,10:00),(9:30,11:00),(11:00,12:30),(13:30,14:00),(14:00,18:00)]

final endresult :

result = [(9:00,12:30), (13:30,18:00)]

now my thought was, when I rearrange the 'taskList' in the manner I questioned

taskListT1 = [(9:00,),(10:00,9:30),(11:00,11:00),(12:30,13:30),(14:00,14:00),(18:00,)]

now I can eliminate those tuples (a,b) where a >= b:

taskListT2 = [(9:00,),(12:30,13:30),(18:00,)]

and transform back:

result = [(9:00,12:30), (13:30,18:00)]
like image 969
Andreas John Avatar asked Dec 11 '25 00:12

Andreas John


1 Answers

Well, here is the solutions with yield:

# transform forwards
def transform_pairs( lst ):
    it = iter(lst)
    a,last = next(it)
    yield [a]
    for a,b in it:
        yield last, a
        last = b
    yield [last]

Transforming the list back should look very similar, but I'll leave that to the reader.

Here is another slightly more complicated one that can transform in both directions. It yield tuples because lists of fixed length are lame.

from itertools import chain

def transform( iterable, offset):
    it = chain.from_iterable(iterable) # turn it back to one long list.
    if offset:
        yield next(it), # the trailing `,` makes this a tuple.
    for item in it:
        try:
            x = next(it)
        except StopIteration: # there is no 2nd item left
            yield item,
        else:
             yield item, x # yield the pair

print list(transform(transform([[1,2],[3,4],[5,6],[7,8]], True), False))
like image 77
Jochen Ritzel Avatar answered Dec 13 '25 15:12

Jochen Ritzel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!