Convert carry-add loop to a map or reduce to one-liner
Your code has a lot of copying in it. In the default case (where direction is left) you copy the array three times. This seems like a lot. There are various minor improvements you can make, for example instead of

v = v[::-1]


you can write

v.reverse()


which at least re-uses the space in v.

But I think that it would be much better to reorganize the whole program so that you store your bignums the other way round (with the least significant word at the start of the list), so that you can always process them in the convenient direction.
The parameters direction and word_size are part of the description of the data in z. So it would make sense to implement this code as a class to keep these values together. And then you could ensure that the digits always go in the convenient direction for your canonicalization algorithm.

class Bignum(object):
    def __init__(self, word_size):
        self._word_size = word_size
        self._mod = 2 ** word_size
        self._digits = []

    def canonicalize(self, carry = 0):
        """
        Add `carry` and canonicalize the array of digits so that each
        is less than the modulus.
        """
        assert(carry &gt;= 0)
        for i, d in enumerate(self._digits):
            carry, self._digits[i] = divmod(d + carry, self._mod)
        while carry:
            carry, d = divmod(carry, self._mod)
            self._digits.append(d)

Python already has built-in support for bignums, anyway, so what exactly are you trying to do here that can't be done in vanilla Python?

Edited to add: I see from your comment that I misunderstood the context in which this function would be used (so always give us the context!). It's still the case that you could implement what you want using Python's built-in bignums, for example if you represented your key as an integer then you could write something like:

def fold(key, k, word_size):
    mod = 2 ** (k * word_size)
    accum = 0
    while key:
        key, rem = divmod(key, mod)
        accum += rem
    return accum % mod


but if you prefer to represent the key as a list of words, then you could still implement the key-folding operation directly:

from itertools import izip_longest

class WordArray(object):
    def __init__(self, data = [], word_size = 8):
        self._word_size = word_size
        self._mod = 1 &lt;&lt; word_size
        self._data = data

    def fold(self, k):
        """
        Fold array into parts of length k, add them with carry, and return a
        new WordArray. Discard the final carry, if any.
        """
        def folded():
            parts = [xrange(i * k, min((i + 1) * k, len(self._data))) 
                     for i in xrange((len(self._data) + 1) // k)]
            carry = 0
            for ii in izip_longest(*parts, fillvalue = 0):
                carry, z = divmod(sum(self._data[i] for i in ii) + carry, self._mod)
                yield z
        return WordArray(list(folded()), self._word_size)