BatWannaBe BatWannaBe - 1 year ago 127
Python Question

Unwrapping tuple values for list indices

Disclaimer:beginner, self-teaching Python user.

A pretty cool feature of ndarrays is their ability to accept a tuple of integers as indices (e.g.

myNDArray[(1,2)] == myNDArray[1][2]
). This allows me to leave the indices unspecified as a variable (e.g. indicesTuple ) until a script determines what part of an ndarray to work with, in which case the variable is specified as a tuple of integers and used to access part of an ndarray (e.g.
). The utility in using a variable is that the LENGTH of the tuple can be varied depending on the dimensions of the ndarray.

However, this limits me to working with arrays of numerical values. I tried using lists, but they can't take in a tuple as indices (e.g.
gives an error.). Is there a way to "unwrap" a tuple for list indices as one could for function arguments? Or something far easier or more efficient?

UPDATE: Holy shite I forgot this existed. Basically I eventually learned that you can initialize the ndarray with the argument dtype=object, which allows the ndarray to contain multiple types of Python objects, much like a list. As for accessing a list, as a commenter pointed out, I could use a for-loop to iterate through the variable indicesTuple to access increasingly nested elements of the list. I still don't know how to edit the element in-place for a list using a variable tuple of indices, though.

Answer Source

I'm interpreting your question as:

I have an N-dimensional list, and a tuple containing N values (T1, T2... TN). How can I use the tuple values to access the list? I don't know what N will be ahead of time.

I don't know of a built-in way to do this, but you can write a method that iteratively digs into the list until you reach the innermost value.

def get(seq, indices):
    for index in indices:
        seq = seq[index]
    return seq

seq = [

indices = [0,1,0]
print get(seq, indices)



You could also do this in one* line with reduce, although it won't be very clear to the reader what you're trying to accomplish.

print reduce(lambda s, idx: s[idx], indices, seq)

(*if you're using 3.X, you'll need to import reduce from functools. So, two lines.)

If you want to set values in the N-dimensional list, use get to access the second-deepest level of the list, and assign to that.

def set(seq, indices, value):
    innermost_list = get(seq, indices[:-1])
    innermost_list[indices[-1]] = value
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download