17

In Python, we have a convenient function enumerate:

for i,item in enumerate(foo_list):
    do something

Is there a Matlab equivalent to enumerate?

For now, what I can think of is something like the following (Matlab code):

i=1;
for foo=foo_list
    ....
    i=i+1;
end
wdg
  • 1,687
  • 5
  • 17
  • 29
  • @jubobs, I agree with you. I supported similar proposal before but I remember it was cancelled. I'll take a look at the site. – wdg Aug 24 '14 at 13:08

3 Answers3

15

As far as I know, there is no equivalent of enumerate in Matlab. The most common way to do this is:

for i = 1:length(foo_list)
    item = foo_list(i);
    % do stuff with i, item
end
Bas Swinckels
  • 18,095
  • 3
  • 45
  • 62
  • 6
    (1) it is best [not to use `i` as a variable name in Matlab](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab). (2) It might be more robust to use `numel` rather than `length` in case `foo_list` is not 1D... – Shai Aug 24 '14 at 07:59
  • 1
    @Shai everyone uses `i` as an index, that is not going to change, whatever people recommend. If you do need a complex number, it is therefore better to use `1i` instead of `i`, to avoid confusion. I see it as a design mistake of Matlab that they gave a special meaning to such a common variable. – Bas Swinckels Aug 24 '14 at 08:07
  • While I didn't specify in the question. In Python, we can do the same using `for i=1 in range(len(foo_list)):`, but we also have `enumerate` which is more elegant. – wdg Aug 24 '14 at 13:10
  • “everyone uses `i` as an index” is patently false. Even before MATLAB, I used `ii`. Back in the day, it was much easier to search for “ii” in source code than “i”, the latter required a more complex regex search command. I still see a lot of people using `ii` for their loops, even if it is just out of habit. – Cris Luengo Jun 27 '20 at 14:09
3

Seems there is no equivalent in Matlab. However if you have a simple 1 x X array you can define it yourself (if you don't worry about performance):

enumerate = @(values) [1:length(values); values]

a = [6 5 4]
for i=enumerate(a)
    do something with i
end

Of course the clean way would be to wrap this inside a general toolkit and add an assert that a is indeed a 1 x X vector.

2

It's easy to achieve by defining a new class for the iteration:

classdef enumerate < handle
   properties(Access = private)
      IterationList;
   end
   
   methods 
       function self = enumerate(in)
           self.IterationList = in;
       end
       function [varargout] = subsref(self, S)
           item = subsref(self.IterationList,S);
           num = S.subs{2};
           out.item = item;
           out.num = num;
           varargout = {out};
       end
       function [m,n] = size(self)
           [m,n] = size(self.IterationList);
       end
   end
end

You can use it in this way:

for t = enumerate(linspace(0,1,10));
disp(['num is: ',num2str(t.num),'item is: ',num2str(t.item)]); 
end

And will get this output:

num is: 1item is: 0

num is: 2item is: 0.11111

num is: 3item is: 0.22222

num is: 4item is: 0.33333

num is: 5item is: 0.44444

num is: 6item is: 0.55556

num is: 7item is: 0.66667

num is: 8item is: 0.77778

num is: 9item is: 0.88889

num is: 10item is: 1

Jiaqi Cai
  • 21
  • 1
  • It’s a neat idea, but this will slow down the loop significantly. Custom classes are always a lot slower in MATLAB than builtin types. – Cris Luengo Jun 27 '20 at 14:26
  • Hi Cris, Thanks for pointing out this! Yes, the class overloads built-in method subsref. I guess JIT won’t work well here. – Jiaqi Cai Jun 28 '20 at 17:54