Skip to main content
added 45 characters in body
Source Link
Peilonrayz
  • 44.6k
  • 7
  • 80
  • 158
def get_top_level_matching_pairs(
    expression: str,
    mapping: dict[str, str],
) -> list[tuple[int, int, int, int]]:
    def head_starts_with_one_from(match_targets: Iterable[str]) -> Optional[str]:
        for m in match_targets:
            if expression.startswith(m, i):
                return m
        return None
    res = []
    queue = []
    i = 0
    while i < len(expression):
        if open := head_starts_with_one_from(mapping.keys()):
            queue.append((i, mapping[open]open))
            i += len(open)
        elif close := head_starts_with_one_from(mapping.values()):
            if not queue:
                # raise closing sequence without an opening.
            index, matchfirst_match = queue.pop()
            match = mapping[first_match]
            if match != close:
                # raise mismatched opening and closing characters.
            if not queue:  # This closing token closes a top-level opening sequence, so add the result
                res.append((index, index + len(matchfirst_match), i, i + len(close)))
            i += len(close)
        else:
            i += 1
    return res
def get_top_level_matching_pairs(
    expression: str,
    mapping: dict[str, str],
) -> list[tuple[int, int, int, int]]:
    def head_starts_with_one_from(match_targets: Iterable[str]) -> Optional[str]:
        for m in match_targets:
            if expression.startswith(m, i):
                return m
        return None
    res = []
    queue = []
    i = 0
    while i < len(expression):
        if open := head_starts_with_one_from(mapping.keys()):
            queue.append((i, mapping[open]))
            i += len(open)
        elif close := head_starts_with_one_from(mapping.values()):
            if not queue:
                # raise closing sequence without an opening.
            index, match = queue.pop()
            if match != close:
                # raise mismatched opening and closing characters.
            if not queue:  # This closing token closes a top-level opening sequence, so add the result
                res.append((index, index + len(match), i, i + len(close)))
            i += len(close)
        else:
            i += 1
    return res
def get_top_level_matching_pairs(
    expression: str,
    mapping: dict[str, str],
) -> list[tuple[int, int, int, int]]:
    def head_starts_with_one_from(match_targets: Iterable[str]) -> Optional[str]:
        for m in match_targets:
            if expression.startswith(m, i):
                return m
        return None
    res = []
    queue = []
    i = 0
    while i < len(expression):
        if open := head_starts_with_one_from(mapping.keys()):
            queue.append((i, open))
            i += len(open)
        elif close := head_starts_with_one_from(mapping.values()):
            if not queue:
                # raise closing sequence without an opening.
            index, first_match = queue.pop()
            match = mapping[first_match]
            if match != close:
                # raise mismatched opening and closing characters.
            if not queue:  # This closing token closes a top-level opening sequence, so add the result
                res.append((index, index + len(first_match), i, i + len(close)))
            i += len(close)
        else:
            i += 1
    return res
Source Link
Peilonrayz
  • 44.6k
  • 7
  • 80
  • 158

  • In my opinion head_starts_with_one_from would be cleaner by using a generator expression:

    def head_starts_with_one_from(match_targets: Iterable[str]) -> Optional[str]:
        return next(
            (
                m
                for m in match_targets
                if expression.startswith(m, i)
            ),
            None
        )
    

    Or better yet, a plain old for loop.

    def head_starts_with_one_from(match_targets: Iterable[str]) -> Optional[str]:
        for m in match_targets:
            if expression.startswith(m, i):
                return m
        return None
    
  • Because you aren't storing start_index in queue your code can't work with nested brackets. We've now got rid of the need for start_index. You didn't really need start_match see next bullet point.

    queue.append((i, mapping[open]))
    
  • You never use stack_head, so you don't need to use the walrus operator there.

  • You can use elif and else to get rid of the continues.

  • You can use guard statements to prevent the arrow anti-pattern.

    if queue.pop() != close:
        # raise mismatched opening and closing characters.
    
def get_top_level_matching_pairs(
    expression: str,
    mapping: dict[str, str],
) -> list[tuple[int, int, int, int]]:
    def head_starts_with_one_from(match_targets: Iterable[str]) -> Optional[str]:
        for m in match_targets:
            if expression.startswith(m, i):
                return m
        return None
    res = []
    queue = []
    i = 0
    while i < len(expression):
        if open := head_starts_with_one_from(mapping.keys()):
            queue.append((i, mapping[open]))
            i += len(open)
        elif close := head_starts_with_one_from(mapping.values()):
            if not queue:
                # raise closing sequence without an opening.
            index, match = queue.pop()
            if match != close:
                # raise mismatched opening and closing characters.
            if not queue:  # This closing token closes a top-level opening sequence, so add the result
                res.append((index, index + len(match), i, i + len(close)))
            i += len(close)
        else:
            i += 1
    return res