473,394 Members | 1,671 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

counting items

Okay, I give up.

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)

I tried:

b=len([x for y in a for x in y])

That doesn't work because you would get an iteration over non-sequence.

I tried:

g=lambda x: (1,len(x))[isinstance(x,(list,tuple,dict))]
b=sum(lambda(x) for x in a)

and that didn't work because I get a TypeError from the len function (don't
know why)

I can, of course:

i=0
for x in a:
if isinstance(x,(list,tuple,dict)):
i += len(x)
else:
i += 1

but that's so C-like...

Thanks,
Jul 18 '05 #1
16 1868
"It's me" <it***@yahoo.com> wrote in message
news:uk*****************@newssvr21.news.prodigy.co m...
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
Jul 18 '05 #2
"It's me" <it***@yahoo.com> wrote in message
news:uk*****************@newssvr21.news.prodigy.co m...
Okay, I give up.

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)

<snip>

I've sure seen a lot of questions about the flattening of lists. I found
this version of flatten somewhere, I thought I got it from the Python
Cookbook but I can't find it now. Perhaps it was posted here on c.l.py. I
*don't* claim authorship, I'm merely an admirer of such a clean-looking
solution.

def flatten(a):
if not isinstance(a, (tuple,list)): return [a]
if len(a)==0: return []
return flatten(a[0])+flatten(a[1:])

a = [[1, 2, 4], 4, 5, [2, 3], 6, [6], [], 'askjdf']

print len(flatten(a))

gives the value 10.

Considering how often this comes up, might there be a place for some sort of
flatten() routine in the std dist, perhaps itertools?

-- Paul
Jul 18 '05 #3
It's me wrote:
Okay, I give up.

What's the best way to count number of items in a list [that may contain lists]?

a = [[1,2,4],4,5,[2,3]]

def iterall(seq):
for item in seq:
try:
for subitem in iterall(item):
yield subitem
except TypeError:
yield item

all = [x for x in iterall(a)]
print len(all)

Jul 18 '05 #4
Thanks.

May be flatten should be build into the language somehow....
"Paul McGuire" <pt***@austin.rr._bogus_.com> wrote in message
news:aK*****************@fe1.texas.rr.com...
"It's me" <it***@yahoo.com> wrote in message
news:uk*****************@newssvr21.news.prodigy.co m...
Okay, I give up.

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)
<snip>

I've sure seen a lot of questions about the flattening of lists. I found
this version of flatten somewhere, I thought I got it from the Python
Cookbook but I can't find it now. Perhaps it was posted here on c.l.py.

I *don't* claim authorship, I'm merely an admirer of such a clean-looking
solution.

def flatten(a):
if not isinstance(a, (tuple,list)): return [a]
if len(a)==0: return []
return flatten(a[0])+flatten(a[1:])

a = [[1, 2, 4], 4, 5, [2, 3], 6, [6], [], 'askjdf']

print len(flatten(a))

gives the value 10.

Considering how often this comes up, might there be a place for some sort of flatten() routine in the std dist, perhaps itertools?

-- Paul

Jul 18 '05 #5
Oh, darn. I asked this kind of question before. <plonk, plonk>

Somebody posted an answer before:

def flatten(seq):
for x in seq:
if hasattr(x, "__iter__"):
for subx in flatten(x):
yield subx
else:
yield x

data = [[1,5,2],8,4]
val_to_pos = {}
for i, x in enumerate(flatten(data)):
val_to_pos[x] = i + 1
print val_to_pos

"It's me" <it***@yahoo.com> wrote in message
news:uk*****************@newssvr21.news.prodigy.co m...
Okay, I give up.

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)

I tried:

b=len([x for y in a for x in y])

That doesn't work because you would get an iteration over non-sequence.

I tried:

g=lambda x: (1,len(x))[isinstance(x,(list,tuple,dict))]
b=sum(lambda(x) for x in a)

and that didn't work because I get a TypeError from the len function (don't know why)

I can, of course:

i=0
for x in a:
if isinstance(x,(list,tuple,dict)):
i += len(x)
else:
i += 1

but that's so C-like...

Thanks,

Jul 18 '05 #6
On Wed, 12 Jan 2005 17:42:50 GMT, It's me <it***@yahoo.com> wrote:
Okay, I give up.

What's the best way to count number of items in a list?
How long is a piece of string? There are many different ways, which
give you different trade offs.
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)

I tried:

b=len([x for y in a for x in y])

That doesn't work because you would get an iteration over non-sequence.
And is very unreadable.
I tried:

g=lambda x: (1,len(x))[isinstance(x,(list,tuple,dict))]
b=sum(lambda(x) for x in a)

and that didn't work because I get a TypeError from the len function (don't
know why)


Because you're trying to get the length of an integer, which is what's failing.

If you know that the list nesting is only one deep, you can do something like:

===
#!/usr/local/bin/python

compoundList = [[1,2,4],4,5,[2,3]]

listLengths = [len(item) for item in compoundList if type(item) not in
[int,long,str,float]]
print listLengths

compoundLength = len(compoundList) - len(listLengths) + sum(listLengths)
print compoundLength
===

If the nesting is 2 deep or more, then the next two options that I
would explore would be:

1. Have a look in the standard library. I'm pretty sure that there are
list-manipulation libraries that'll do what you want (not sure on
names, though).
2. Write a function to do what you want. Some sort of recursive thing
should be pretty easy to write. Of course it depends on how fast you
need to go, but that should give you a good first approximation.

Anthony

--
-----------------------------------------------------
HyPEraCtiVE? HeY, WhO aRE YoU cALliNg HypERaCtIve?!
aN************@gmAiL.CoM
-----------------------------------------------------
Jul 18 '05 #7
Yes, Mark, I came up with almost the same code (after reading back old
answers from this list):

def flatten(seq):
for x in seq:
if hasattr(x, "__iter__"):
for subx in flatten(x):
yield subx
else:
yield x

def count_item(data):
return len([(i,x) for i, x in enumerate(flatten(data))])

data = [[1,5,2],8,4]
print count_item(data)
Thanks everybody.

"Mark McEahern" <ma*******@mceahern.com> wrote in message
news:ma**************************************@pyth on.org...
It's me wrote:
Okay, I give up.

What's the best way to count number of items in a list [that may contain lists]?

a = [[1,2,4],4,5,[2,3]]

def iterall(seq):
for item in seq:
try:
for subitem in iterall(item):
yield subitem
except TypeError:
yield item

all = [x for x in iterall(a)]
print len(all)

Jul 18 '05 #8
Mark McEahern wrote:
It's me wrote:
Okay, I give up.

What's the best way to count number of items in a list [that may
contain lists]?

a = [[1,2,4],4,5,[2,3]]

def iterall(seq):
for item in seq:
try:
for subitem in iterall(item):
yield subitem
except TypeError:
yield item

all = [x for x in iterall(a)]
print len(all)


Beware:

py> list(iterall(['a']))
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
File "<interactive input>", line 4, in iterall
...
File "<interactive input>", line 4, in iterall
RuntimeError: maximum recursion depth exceeded

You need to special-case strings. I would do this explicitly, e.g.:

py> def iterall(seq):
.... for item in seq:
.... if isinstance(item, basestring):
.... yield item
.... else:
.... try:
.... for subitem in iterall(item):
.... yield subitem
.... except TypeError:
.... yield item
....
py> list(iterall(['a']))
['a']

but you can also do this by checking for __iter__ as in one of the other
posted solutions. (This takes advantage of the fact that strings use
the __getitem__ protocol for iteration instead of __iter__.)

Steve
Jul 18 '05 #9
"It's me" <it***@yahoo.com> 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))))]

;-)

Bernhard

--
Intevation GmbH http://intevation.de/
Skencil http://skencil.org/
Thuban http://thuban.intevation.org/
Jul 18 '05 #10
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

Jul 18 '05 #11
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.
Jul 18 '05 #12
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
Jul 18 '05 #13
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

Jul 18 '05 #14
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
Jul 18 '05 #15
On Wed, 12 Jan 2005 18:07:47 GMT, "Andrew Koenig" <ar*@acm.org> wrote:
"It's me" <it***@yahoo.com> wrote in message
news:uk*****************@newssvr21.news.prodigy.c 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
Jul 18 '05 #16
On Wed, 2005-01-12 at 20:10 +0100, Bernhard Herzog wrote:
"It's me" <it***@yahoo.com> 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 :-P

--
Craig Ringer

Jul 18 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Andrew Banks | last post by:
I have a table of product orders. It contains a row for "platform" and I need to return how many times each platform is listed in the DB Example data for platform could be: XBOX XBOX XBOX...
4
by: Rob Meade | last post by:
Hi all, Ok - I appreciated I could probably just do this : For Each item IN array intCount = intCount + 1 Next
1
by: zishiri | last post by:
My Operating System is Windows XP. I use Ms Access 2003 My problems are as follows 1. I want a textbox of one form(form2) to count the number of items in one database table and display the...
3
by: jas2803 | last post by:
Hello, I have a table: The person gets to come back as often as possible and choose between 3 different items, A, B C, for the column. They can take as many as they want, column. I want...
4
prn
by: prn | last post by:
Hi folks, I've got another (inherited) puzzle that I don't understand. A report that I need to modify contains a subreport that lists a variable number of items in its detail section and then...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.