Velocity Reviews > counting items

# counting items

Michael Hartl
Guest
Posts: n/a

 01-12-2005
There's a great function called "walk" at that iterates over arbitrary
data (and is recursion-proof) at

http://aspn.activestate.com/ASPN/Coo.../Recipe/118845

It also supplies a recursion-proof way to flatten a list. (Once you
can iterate over an arbitrary sequence, the flattened version is just
[element for element in walk(sequence)].) I use both functions all the
time.

Adding a flatten function (along with walk) to Python sounds like a
good idea to me. Having used Mathematica for many years, which uses
Flatten[] all over the place, I was actually quite surprised to find
that Python didn't have it.

Michael

Leif K-Brooks
Guest
Posts: n/a

 01-12-2005
Paul McGuire wrote:
> Considering how often this comes up, might there be a place for some sort of
> flatten() routine in the std dist, perhaps itertools?

A problem I see is that itertools tries to work across all iterable
types, but flattening can't always be a generalized operation. For
instance, a naive flattening function might turn the list ['foo', 'bar']
into ['f', 'o', 'o', 'b', 'a', 'r'] -- or worse, fall into infinite
recursion -- when the intended result would be to leave the list
unchanged. Of course, a generalized flattening function could take an
argument listing types to ignore, but that can get very complicated very
fast.

Steven Bethard
Guest
Posts: n/a

 01-12-2005
Michael Hartl wrote:
> (Once you can iterate over an arbitrary sequence, the
> flattened version is just
> [element for element in walk(sequence)].)

Or, better yet:

list(walk(sequence))

Steve

Michael Hartl
Guest
Posts: n/a

 01-12-2005
That's cool! Of course, walk returns a generator, so using a list
comprehension to turn it into a list seems natural, but I didn't
realize that list() does the same thing (and neither, apparently, did
the original implementor) -- although, with a little reflection, it
obviously must!

Michael

Steven Bethard
Guest
Posts: n/a

 01-12-2005
Michael Hartl wrote:
> That's cool! Of course, walk returns a generator, so using a list
> comprehension to turn it into a list seems natural, but I didn't
> realize that list() does the same thing (and neither, apparently, did
> the original implementor) -- although, with a little reflection, it
> obviously must!

Yup. Also worth noting is that if you want the scoping rules of
generator expression, but need a list instead, you can just call list
with the generator expression:

py> x
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
NameError: name 'x' is not defined
py> [pow(x, 7, 23) for x in range(10)]
[0, 1, 13, 2, 8, 17, 3, 5, 12, 4]
py> x
9
py> del x
py> x
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
NameError: name 'x' is not defined
py> list(pow(x, 7, 23) for x in xrange(10))
[0, 1, 13, 2, 8, 17, 3, 5, 12, 4]
py> x
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
NameError: name 'x' is not defined

Note that with the generator expression, 'x' doesn't get leaked to the
enclosing scope.

Steve

Bengt Richter
Guest
Posts: n/a

 01-13-2005
On Wed, 12 Jan 2005 18:07:47 GMT, "Andrew Koenig" <(E-Mail Removed)> wrote:

>"It's me" <(E-Mail Removed)> wrote in message
>news:ukdFd.10645\$(E-Mail Removed) om...
>
>> What's the best way to count number of items in a list?
>>
>> For instance,
>>
>> a=[[1,2,4],4,5,[2,3]]
>>
>> I want to know how many items are there in a (answer should be 7 - I don't
>> want it to be 4)

>
>How about this?
>
> def totallen(x):
> if isinstance(x, (list, tuple, dict)):
> return sum(map(totallen, x))
> return 1

Since the requirement is to _count_, not flatten, ISTM your solution is best so far

Regards,
Bengt Richter

Craig Ringer
Guest
Posts: n/a

 01-13-2005
On Wed, 2005-01-12 at 20:10 +0100, Bernhard Herzog wrote:
> "It's me" <(E-Mail Removed)> writes:
>
> > May be flatten should be build into the language somehow....

>
> That shouldn't be necessary as it can easily be written in a single list
> comprehension:
>
> a = [[1,2,4],4,5,[2,3]]
> flat_a = [x for cur, rest in [[a[:1], a[1:]]] for x in cur
> if (not isinstance(x, (list, tuple))
> and (not rest or not cur.append(rest.pop(0)))
> or (x and (cur.append(x[0]) or rest.__setslice__(0, 0, x[1:])))
> or (not x and rest and cur.append(rest.pop(0))))]
>
>

If it means I _never_ have to see that list comprehension again, then
seeing 'flatten' go into itertools would make me very, very happy

--
Craig Ringer

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Dan Python 14 09-01-2006 05:46 AM edwardfredriks Javascript 6 09-07-2005 03:30 PM rbscheer@my-deja.com ASP .Net 1 05-24-2005 07:06 AM Andrew Banks ASP .Net 3 04-01-2004 09:12 PM Rob Meade ASP .Net 4 11-25-2003 01:24 PM

Advertisments