473,387 Members | 1,353 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,387 software developers and data experts.

is_iterable function.

def is_iterable(obj):
try:
iter(obj)
return True
except TypeError:
return False

Is there a better way?

--
Neil Cerutti
Jul 25 '07 #1
9 1801
Neil Cerutti <ho*****@yahoo.comwrote:
Speaking of the iter builtin function, is there an example of the
use of the optional sentinel object somewhere I could see?
for line in iter(open('somefile.txt', 'r').readline, ''):
print line

Jul 25 '07 #2
On 2007-07-25, Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
So there's no reliable way to test for "iterables" other than
actually iterate over the object.
A TypeError exception is perhaps too generic for comfort in this
use case:

def deeply_mapped(func, iterable):
for item in iterable:
try:
for it in flattened(item):
yield func(it)
except TypeError:
yield func(item)

I'd be more confortable excepting some sort of IterationError (or
using an is_iterable function, of course). I guess there's always
itertools. ;)

--
Neil Cerutti
Jul 25 '07 #3
On Wed, 2007-07-25 at 19:26 +0000, Neil Cerutti wrote:
Speaking of the iter builtin function, is there an example of the
use of the optional sentinel object somewhere I could see?
Example 1: If you use a DB-API module that doesn't support direct cursor
iteration with "for row in cursor", you can simulate it this way:

for row in iter(cursor.fetchone, None):
# do something

Example 2: Reading a web page in chunks of 8kB:

f = urllib.urlopen(url)
for chunk in iter(lambda:f.read(8192), ""):
# do something

HTH,

--
Carsten Haese
http://informixdb.sourceforge.net
Jul 25 '07 #4
On 2007-07-25, Carsten Haese <ca*****@uniqsys.comwrote:
On Wed, 2007-07-25 at 19:26 +0000, Neil Cerutti wrote:
>Speaking of the iter builtin function, is there an example of the
use of the optional sentinel object somewhere I could see?

Example 1: If you use a DB-API module that doesn't support direct cursor
iteration with "for row in cursor", you can simulate it this way:

for row in iter(cursor.fetchone, None):
# do something

Example 2: Reading a web page in chunks of 8kB:

f = urllib.urlopen(url)
for chunk in iter(lambda:f.read(8192), ""):
# do something
Ah! Thanks for the examples. That's much simpler than I was
imagining. It's also somewhat evil, but I suppose it conserves a
global name to do it that way.

--
Neil Cerutti
Jul 25 '07 #5
On Jul 25, 3:26 pm, Neil Cerutti <horp...@yahoo.comwrote:
Speaking of the iter builtin function, is there an example of the
use of the optional sentinel object somewhere I could see?
# iterate over random numbers from 1 to 10; use 0 as a sentinel to
stop the iteration
for n in iter(lambda:random.randrange(10), 0):
print n

More generally, iter(callable, sentinel) is just a convenience
function for the following generator:

def iter(callable, sentinel):
while True:
c = callable()
if c == sentinel: break
yield c
George

Jul 25 '07 #6
Carsten Haese wrote:
On Wed, 2007-07-25 at 19:26 +0000, Neil Cerutti wrote:
>Speaking of the iter builtin function, is there an example of the
use of the optional sentinel object somewhere I could see?

Example 1: If you use a DB-API module that doesn't support direct cursor
iteration with "for row in cursor", you can simulate it this way:

for row in iter(cursor.fetchone, None):
# do something
[...]
This would, of course, be a horribly inefficient way to handle a
database result with 1,500,000 rows. Calling fetchall() might also have
its issues. The happy medium is to use a series of calls to fetchmany(N)
with an appropriate value of N.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------

Jul 25 '07 #7
Based on the discussions in this thread (thanks all for your
thoughts), I'm settling for:

def is_iterable(obj):
try:
iter(obj).next()
return True
except TypeError:
return False
except KeyError:
return False

The call to iter will fail for objects that don't support the
iterator protocol, and the call to next will fail for a
(hopefully large) subset of the objects that don't support the
sequence protocol.

This seems preferable to cluttering code with exception handling
and inspecting tracebacks. But it's still basically wrong, I
guess.

To repost my use case:

def deeply_mapped(func, iterable):
""" Recursively apply a function to every item in a iterable object,
recursively descending into items that are iterable. The result is an
iterator over the mapped values. Similar to the builtin map function, func
may be None, causing the items to returned unchanged.
>>import functools
flattened = functools.partial(deeply_mapped, None)
list(flattened([[1], [2, 3, []], 4]))
[1, 2, 3, 4]
>>list(flattened(((1), (2, 3, ()), 4)))
[1, 2, 3, 4]
>>list(flattened([[[[]]], 1, 2, 3, 4]))
[1, 2, 3, 4]
>>list(flattened([1, [[[2, 3]], 4]]))
[1, 2, 3, 4]

"""
for item in iterable:
if is_iterable(item):
for it in deeply_mapped(func, item):
if func is None:
yield it
else:
yield func(it)
else:
if func is None:
yield item
else:
yield func(item)
--
Neil Cerutti
Jul 26 '07 #8
On Thu, 26 Jul 2007 15:02:39 +0000, Neil Cerutti wrote:
Based on the discussions in this thread (thanks all for your
thoughts), I'm settling for:

def is_iterable(obj):
try:
iter(obj).next()
return True
except TypeError:
return False
except KeyError:
return False

The call to iter will fail for objects that don't support the
iterator protocol, and the call to next will fail for a
(hopefully large) subset of the objects that don't support the
sequence protocol.
And the `next()` consumes an element if `obj` is not "re-iterable".

Ciao,
Marc 'BlackJack' Rintsch
Jul 26 '07 #9
On 2007-07-26, George Sakkis <ge***********@gmail.comwrote:
That's not the only problem; try a string element to see it
break too. More importantly, do you *always* want to handle
strings as iterables ?

The best general way to do what you're trying to is pass
is_iterable() as an optional argument with a sensible default,
but allow the user to pass a different one that is more
appropriate for the task at hand:

def is_iterable(obj):
try: iter(obj)
except: return False
else: return True
def flatten(obj, is_iterable=is_iterable):
That makes good sense.

Plus the subtly different way you composed is_iterable is clearer
than what I originally wrote. I haven't ever used a try with an
else.
if is_iterable(obj):
for item in obj:
for flattened in flatten(item, is_iterable):
yield flattened
else:
yield obj

By the way, it's bad design to couple two distinct tasks:
flattening a (possibly nested) iterable and applying a function
to its elements. Once you have a flatten() function,
deeply_mapped is reduced down to itertools.imap.
I chose to implement deeply_mapped because it illustrated the
problem of trying to catch a TypeError exception when one might
be thrown by some other code. I agree with your opinion that it's
a design flaw, and most of my problems with the code were caused
by that flaw.

--
Neil Cerutti
Jul 26 '07 #10

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

Similar topics

3
by: domeceo | last post by:
can anyone tell me why I cannot pass values in a setTimeout function whenever I use this function it says "menu is undefined" after th alert. function imgOff(menu, num) { if (document.images) {...
5
by: phil_gg04 | last post by:
Dear Javascript Experts, Opera seems to have different ideas about the visibility of Javascript functions than other browsers. For example, if I have this code: if (1==2) { function...
2
by: laredotornado | last post by:
Hello, I am looking for a cross-browser way (Firefox 1+, IE 5.5+) to have my Javascript function execute from the BODY's "onload" method, but if there is already an onload method defined, I would...
2
by: sushil | last post by:
+1 #include<stdio.h> +2 #include <stdlib.h> +3 typedef struct +4 { +5 unsigned int PID; +6 unsigned int CID; +7 } T_ID; +8 +9 typedef unsigned int (*T_HANDLER)(void); +10
8
by: Olov Johansson | last post by:
I just found out that JavaScript 1.5 (I tested this with Firefox 1.0.7 and Konqueror 3.5) has support not only for standard function definitions, function expressions (lambdas) and Function...
3
by: Beta What | last post by:
Hello, I have a question about casting a function pointer. Say I want to make a generic module (say some ADT implementation) that requires a function pointer from the 'actual/other modules'...
2
by: f rom | last post by:
----- Forwarded Message ---- From: Josiah Carlson <jcarlson@uci.edu> To: f rom <etaoinbe@yahoo.com>; wxpython-users@lists.wxwidgets.org Sent: Monday, December 4, 2006 10:03:28 PM Subject: Re: ...
28
by: Larax | last post by:
Best explanation of my question will be an example, look below at this simple function: function SetEventHandler(element) { // some operations on element element.onclick = function(event) {
4
by: alex | last post by:
I am so confused with these three concept,who can explained it?thanks so much? e.g. var f= new Function("x", "y", "return x * y"); function f(x,y){ return x*y } var f=function(x,y){
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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,...

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.