Well, as usual there are compromises in everything and the mgrid/ogrid functionality is the way it currently is for some good reasons. The first reason is that python appears to be fairly sloppy about how it passes indexing arguments to the __getitem__ method. It passes a tuple containing the arguments in all cases except when it has one argument, in which case it just passes that argument. This means that it is hard to tell a tuple argument from several non-tuple arguments. For example, the following two produce exactly the same call to __getitem__ :
(__getitem__ receives a single tuple (1,2,3)), but different from:
(__getitem__ receives a single list = [1,2,3]). This seems like a bug to me, but is probably considered a feature by somebody. In any case, this is workable, but a bit annoying in that tuple arguments just aren't going to work well.
The second problem is that the current implementation is fairly efficient because it forces all arguments to the same type so as to avoid some unnecessary copies (I think). Once you allow non-slice arguments, this is hard to maintain.
That being said, attached is a replacement for index_tricks.py that should implement a reasonable set of features, while only very slightly altering performance. I have only touched nd_grid. I haven't fixed the documentation string yet, nor have I added tests to test_index_tricks.py, but will do that if the changes will be accepted into numpy. With the new version, old stuff should work as usual, except that mgrid now returns a list of arrays instead of an array of arrays (note that this change will cause current test_index_tricks.py to fail). With the new changes, you can now do:
The following will work as expected:
But this will not:
mgrid[(1,2,3)] # same as mgrid[1,2,3], but different from mgrid[[1,2,3]]
Given these limitations, this seems like a fairly useful addition. If this looks usable, I will clean up and add tests if desired. If not, I recommend adding a ndgrid function to numpy that does the equivalent of matlab [X,Y,Z,...] = ndgrid(x,y,z,...) and then making the current meshgrid just call that changing the order of the first two arguments.
David M. Kaplan wrote:
python appears to be fairly sloppy about how it passes indexing arguments to the __getitem__ method.
I do not generally find the word 'sloppy' to be descriptive of Python.
It passes a tuple containing the arguments in all cases except when it has one argument, in which case it just passes that argument.
Well, not quite. The bracket syntax is for passing a key (a single object) to __getitem__.
For example, the following two produce exactly the same call to __getitem__ : mgrid[1,2,3] mgrid[(1,2,3)]
Well, yes. Note::
>>> x = 1,2,3 >>> type(x) <type 'tuple'>
In Python it is the commas, not the paretheses, that is determining the tuple type.
So perhaps the question you raise could be rephrased to "why does an ndarray (not Python) handle treat a list 'index' differently than a tuple 'index'?" I do not know the history of that decision, but it has been used to provide some additional functionality.
Cheers, Alan Isaac
Alan G Isaac
David M. Kaplan