# What for -- for? (was A bug?)

Rustom Mody rustompmody at gmail.com
Wed Oct 29 04:22:13 CET 2014

```On Wednesday, October 29, 2014 7:47:47 AM UTC+5:30, Denis McMahon wrote:
> On Tue, 28 Oct 2014 01:29:28 +0000, Joshua Landau wrote:
>
> > On 28 October 2014 00:36, Denis McMahon wrote:
> >>
> >> d = [[list(range(1,13))[i*3+j] for j in range(3)] for i in range(4)]
> >
> > A quick note. Ranges (even 2.7's xrange) are all indexable. The cast to
> > a list isn't needed.
>
> Until you apply Chris' slicing trick, and then:
>
> >>> [list(range(1,13))[i*3:i*3+3] for i in range(4)]
> [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
> >>> [range(1,13)[i*3:i*3+3] for i in range(4)]
> [range(1, 4), range(4, 7), range(7, 10), range(10, 13)]
> >>>
>
> Depends how important it is that you get a list and not a range object ;)

Heh!

Strange that you say this in this context!
Yesterday I was trying to introduce python to some senior computer scientists.

Tried showing a comprehension-based dir-walker vs a for-loop based one:

def dw(p):
if isfile(p):
return [p]
else:
return [p] + [c for f in listdir(p) for c in dw(p+'/'+f)]

def dw(p):
if isfile(p):
return [p]
else:
ls = [p]
for f in listdir(p):
ls = ls+[f]
for c in dw(p+'/'+f):
ls = ls+[c]
return ls

Comment to me : "Well this is neat and compact, but it does not add
anything fundamental (over usual index based for-loops)"

I tried to say that 'for' over general sequences is quite different
and significantly more powerful than C/Pascal for over indexes +
explicit indexing.

In particular the fact that in python-3:
>>> range(1,10)
range(1, 10)

and not like python2's

>>> range(1,10)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

seemed to convincingly show that python's range is just
'notional' like Pascal's subrange types and not an actual sequence.

That
>>> range(10)+range(10)

works in python 2 but not 3

does not help my case at all!

I'd be interested in thoughts on this -- is a range a 'real' or a 'notional'
sequence?

Related point: "A range is a sequence"
How to prove this introspectively?

ie if I do:

>>> type([]).__mro__
(<class 'list'>, <class 'object'>)
>>> type(range(10)).__mro__
(<class 'range'>, <class 'object'>)
>>>

How to see that list and range are both sequences?
Or more generally how to to introspectively discover (ie not by reading docs!!)
the abstract base classes -- eg sequence, iterable etc -- for an arbitrary
object?

```