Alan Gauld wrote:
>>map calls, list comprehension, etc.  For loops, etc.
>>work by indexing a  sequences from zero to a higher
>>index until out-of-bounds is reached.  
> 
> 
> What makes you think that?
> So far as I know for loops work by calling next on 
> an iterator until nothing gets returned, no indexes 
> involved.(At least not in the for loop) But they could 
> just as well work by calling the len() function and 
> iterating that number of times. And len() could be 
> stored as part of the data structure ala Pascal arrays.

Hmm. From the language ref description of 'for':
"The expression list is evaluated once; it should yield an iterable object."

which begs the question of, what is an iterable object? The iterator 
protocol was introduced in Python 2.2; the "What's New" document give a 
good description of the old and new methods of iterating. Prior to 
Python 2.2, the _only_ way to make an object iterable was to give in a 
__getitem__() method. With Python 2.2 you can alternatively define 
__iter__().
http://www.python.org/doc/2.2.3/whatsnew/node4.html

 From the language ref description of __getitem__():
"Note: for loops expect that an IndexError will be raised for illegal 
indexes to allow proper detection of the end of the sequence."

In fact a class that just defines __getitem__() can be iterated in a for 
loop:

  >>> class stepper:
  ...   def __getitem__(self, i):
  ...     if i < 5: return i
  ...     raise IndexError
  ...
  >>> for i in stepper(): print i
  ...
0
1
2
3
4

> 
> The point being that it is dangerous to assume how 
> a language feature works internally, it can change from 
> version to version.

Dangerous to assume, maybe, but special methods are there to be used, 
and the usage is generally well understood if not always well documented.
> 
> In this case the iterator solution means that the for 
> loop can work on any iterable entity - like files for 
> instance.

Yes, and for backward compatibility it also works on anything 
implementing __getitem__(). In fact strings have no __iter__() method, 
they use __getitem__():
  >>> ''.__iter__
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
AttributeError: 'str' object has no attribute '__iter__'
  >>> ''.__getitem__
<method-wrapper object at 0x00A32E50>

> 
> 
>>But why does this work?
>>
>>
>>>>>class stepper:
>>
>>...     def __getitem__(self, i):
>>...         return self.data[i]
>>...
>>
>>>>>'p' in X
>>
>>True
>>
>>What does 'in' have to do with indexing?
> 
> 
> Nothing unless its implementation uses a while loop
> and index, but thats unlikely.

But that is pretty close to what actually happens, according to the 
language ref docs for 'in' (see my previous post).

Kent

_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to