1

I am implementing a local optimization that fuses objects together. In the simplest form, given a list:

[0, 3, 5, 8, 1, 2, 9, 0, 3, 5]

I would like to group into:

[[0, 3], 5, 8, 1, 2, 9, [0, 3], 5]

which is based on a provided criterion:

def is_group(a, b):
    return a == 0 and b == 3

My current solution seems a bit convoluted, and am looking for most pythonic approach:

def pairwise(iterable):
    for (a, b) in zip(iterable, iterable[1:]):
        yield (a, b)
    yield (iterable[-1], None)  # handle edge case

def fuse(ops):
    ops_new = []
    skip_next = False
    for (a, b) in pairwise(ops):
        if is_group(a, b):
            ops_new.append([a, b])
            skip_next = True
        elif skip_next:
            skip_next = False
        elif:
            ops_new.append(a)

I've looked at groupby, which is the closest but aren't quite sure how to make it work since here the criterion depends on pairwise arguments.

Edit: Another way to ask the question is I am basically trying to do pattern search and replace with lists (e.g. regex for lists).

3
  • What's the edge-case you are handling in pairwise? IOW, why do you need to consider the last element against None? Commented Oct 15, 2017 at 17:32
  • Thanks for the question. If I don't include that handling, then pairwise just returns (0, 3), (3, 5), (5, 8), ..., (3, 5). My fuse operation never appends b, so my result would always be missing the last element. Commented Oct 15, 2017 at 18:01
  • Aha, that makes sense. Well, then in that case the only thing I would change would be from itertools import zip_longest, islice Then simply zip_longest(x, islice(x, 1, None)) instead of your pairwise Commented Oct 15, 2017 at 18:26

1 Answer 1

1

Custom isolate_group function:

def isolate_group(pair, l):
    result = []
    idx_skip = -1

    for i in range(len(l)):
        if i == idx_skip:
            continue
        if l[i:i+2] == pair:
            result.append(l[i:i+2])
            idx_skip = i+1
        else:
            result.append(l[i])

    return result

Test 1:

print(isolate_group([0,3], [0, 3, 5, 8, 1, 2, 9, 0, 3, 5]))

The output:

[[0, 3], 5, 8, 1, 2, 9, [0, 3], 5]

Test 2:

print(isolate_group([0,3], [0, 3, 5, 8, 0, 3, 9, 5, 0, 3]))

The output:

[[0, 3], 5, 8, [0, 3], 9, 5, [0, 3]]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.