Merge Sort from Scratch in Python
At the end of the code, it looks like merge() is called by nesting the array in a list and the result is the 0th element of the returned list.  This is an unusual calling convention, is different than the way the built in sorted() is called, and it is not documented, which would likely lead to many errors.  If this interface is needed for the algorithm to work, it would be better if merge() handled these details an then called another function.  For example:

def merge(array):
    return _merge([array], True)

def _merge(array, True):
    ... same as your original code ...


The boolean argument split appears to control whether merge() splits the array into two smaller parts or merges two smaller parts together.  This complicates the logic and makes it more difficult to follow.  It would be better two have two separate functions.

It is also appears that the code takes parts of a recursive implementation and parts from an iterative implementation.  For example, merge is called recursively to split the array into smaller arrays, but for i in range(0, len(array), 2): loops over a list of subarrays and merges them in pairs.

The essence of merge sort is: if the array isn't sorted, split it into two parts, sort both parts separately, and then merge the two parts together.  Here is a recursive implementation:

def merge_sort(array):
    if is_not_sorted(array):
        # split array in two
        middle = len(array) // 2
        left_half = array[:middle]
        right_half = array[middle:]

        # sort each part
        left_half = merge_sort(left_half)
        right_half = merge_sort(right_half)

        array = merge_halves(left_half, right_half)
        return array

    else:
        # array is already sorted
        return array


Usually, if is_not_sorted(): is implemented as if len(array) &gt; 1: (if there is more than one item in the array, it is presumed to be unsorted).  But some implementations (like Python's builtin sorted or list.sort) check small lists to see if they are already sorted.  Also, the two halves are usually sorted using a recursive call to merge_sort(), but some implementations may use a different sorting algorithm if the array is small.

merge_halves() is then basically the same as the while pointer_a &lt; len(array[i])... loop in your code (with a few simplifications):

def merge_halves(left, right):
    merged_array = []
    pointer_a = 0
    pointer_b = 0
    while pointer_a &lt; len(left) and pointer_b &lt; len(right):
        if left[pointer_a] &lt;= right[pointer_b]:
            merged_array.append(left[pointer_a])
            pointer_a += 1

        elif right[pointer_b] &lt; left[pointer_a]:
            merged_array.append(right[pointer_b])
            pointer_b += 1

    #At the end of one subarray, extend temp by the other subarray
    if pointer_a &lt; len(left):
        merged_array.extend(left[pointer_a:])

    elif pointer_b &lt; len(right):
        merged_array.extend(right[pointer_b:])

    return merged_array


An iterative version might look something like this (code on the fly, so may have errors):

def merge(array):
    # make all the sub arrays 1 item long.  A more intelligent version might
    # split it into runs that are already sorted
    array = [[item] for item in array]

    while len(array) &gt; 1:
        temp = []

        for i in range(0, len(array), 2):
            #Pointers are used to check each element of the two mergin arrays
            pointer_a = 0
            pointer_b = 0

            #Loop to merge the array
            while pointer_a &lt; len(array[i]) and pointer_b &lt; len(array[i+1]):
                if array[i][pointer_a] &lt;= array[i + 1][pointer_b]:
                    temp.append(array[i][pointer_a])
                    pointer_a += 1

                else:
                    temp.append(array[i + 1][pointer_b])
                    pointer_b += 1

            if pointer_a &lt; len(array[i]):
                temp.extend(array[i][x])

            elif pointer_b &lt; len(array[i + 1]):
                temp.extend(array[i + 1][x])


        #there were an odd number of sub_arrays, just copy over the last one
        if len(sub_arrays) % 2:
            temp.append(sub_arrays[-1])

        array = temp

    return array[0]