Traffic speed limit check for intervals
First, let's look at your answer with comments:

def speed_check(limits, speeds):
  # Explicit assignment of temporary variables
  i, j = 0, 0
  prev_limit_range, prev_speed_range = 0, 0
  # Assumption that speeds and limits will not change during iteration
  while j &lt; len(speeds) and i &lt; len(limits):
    # Multiple if statements make it so that we can't just swap lines of
    # code without breaking things.
    if limits[i][0] &lt; speeds[j][0]: # speed &gt; limit would be more readable
      return True
    # Operator precedence does not jump to the eye. Use parenthesis
    if limits[i][1] + prev_limit_range &lt; speeds[j][1] + prev_speed_range:
      prev_limit_range += limits[i][1]
      i += 1
    elif limits[i][1] + prev_limit_range &gt; speeds[j][1] + prev_speed_range:
      prev_speed_range += speeds[j][1]
      j += 1
    else:
    # Manual incrementation of local variables. 
      prev_limit_range += limits[i][1]
      prev_speed_range += speeds[j][1]
      i += 1
      j += 1

  return False


Python-wise there are multiple parts of your implementation that could be tackled differently. Let's see what we could do. 

If you think about this problem graphically, drawing an x-axis for distance and a y-axis for speed, then all you want is to check whether the curve for actual speed ever crosses the curve for speed limits.

You could break down your problem into subparts:

def get_graph(speedlist):
    """Generate a list of tuples into a flatten list as in:
    [(1,2), (3, 4)] -&gt; [1, 1, 3, 3, 3, 3]       
    """
    return [item for x in [y[1]*[y[0]] for y in speedlist] for item in x]

def check_exceeds(speeds, limits):
    speed_graph = get_graph(speeds)
    limits_graph = get_graph(limits)
    return any([x &gt; y for x, y in zip(speed_graph, limits_graph)])


This approach avoids three issues I see in your implementation:  excess of if-statements, explicit indexing, and explicit iteration. Why are these issues? Well, it's easy to make mistakes when indexing and manually iterating, and it's easy to forget possible branches when using if/else clauses. Python offers a lot of tooling so that you don't have to do everything yourself, and it's considered good practice to leverage that tooling to make your code both more readable and safe.

For your assertions, there is also no need to compare to True nor False, in case your function is defined in such a way that it returns a boolean: 

assert check_exceeds([(30, 15), (55, 20)], [(30, 15), (55, 20)])
assert not check_exceeds([(30, 15), (55, 20)], [(30, 14), (65, 20)])


(quick answer as I was answering the post in StackOverflow before it migrated)