interating over single element array

T

T. Crane

Hi all,

Can someone please explain to me why I can't do something like this:

a = 1

for value in a:
print str(value)

If I run this I get the error:

'int' object is not iterable

Obivously this is an absurd example that I would never do, but in my
application the length of 'a' can be anything greater than 0, and I want to
be able to handle cases when 'a' has only one element without coding a
special case just in the event that len(a) = 1.

any suggestions are appreciated,
trevis
 
M

Marc 'BlackJack' Rintsch

Can someone please explain to me why I can't do something like this:

a = 1

for value in a:
print str(value)

If I run this I get the error:

'int' object is not iterable

Well the message explains why you can't do this. `a` is bound to an
integer and integers are not iterable.
Obivously this is an absurd example that I would never do, but in my
application the length of 'a' can be anything greater than 0, and I want to
be able to handle cases when 'a' has only one element without coding a
special case just in the event that len(a) = 1.

``len(a)`` wouldn't work either because integers have no "length":

In [16]: a = 1

In [17]: len(a)
---------------------------------------------------------------------------
exceptions.TypeError Traceback (most recent call last)

/home/new/<ipython console>

TypeError: len() of unsized object
any suggestions are appreciated,

Yes, don't try iterating over objects that are not iterable. ;-)

What you *can* do is iterating over lists, tuples or other iterables with
just one element in them. Try ``a = [1]``.

Ciao,
Marc 'BlackJack' Rintsch
 
T

T. Crane

Yes, don't try iterating over objects that are not iterable. ;-)

Ah, yes... I hadn't thought of that :)


thanks,
trevis
What you *can* do is iterating over lists, tuples or other iterables with
just one element in them. Try ``a = [1]``.

Ciao,
Marc 'BlackJack' Rintsch
 
B

Basilisk96

Yes, don't try iterating over objects that are not iterable. ;-)

Ah, yes... I hadn't thought of that :)

thanks,
trevis


What you *can* do is iterating over lists, tuples or other iterables with
just one element in them. Try ``a = [1]``.
Ciao,
Marc 'BlackJack' Rintsch


You can also do this (if tuples are okay in your case):

a = 1,

The comma turns 'a' into a tuple (1,) which is both iterable and has a
length of 1.

I have run into this issue before with a function that took a list of
filenames (strings), and needed to iterate over the list to operate on
the input files. For the case when the input would be a single file, I
needed to turn the input string into an iterable such that the 'for'
loop would not iterate on the filename characters (a rather
undesirable gotcha, you understand :) ). So I solved my problem like
this:

def loadfiles(filelist):
if not isinstance(filelist, list):
filelist = filelist,
for filename in filelist:
f = open(filename,'r')
#do interesting stuff with file, etc...

...and it's been working very well.

Cheers,
-Basilisk96
 
T

Terry Reedy

| You can also do this (if tuples are okay in your case):
|
| a = 1,
|
| The comma turns 'a' into a tuple (1,) which is both iterable and has a
| length of 1.
|
| I have run into this issue before with a function that took a list of
| filenames (strings), and needed to iterate over the list to operate on
| the input files. For the case when the input would be a single file, I
| needed to turn the input string into an iterable such that the 'for'
| loop would not iterate on the filename characters (a rather
| undesirable gotcha, you understand :) ). So I solved my problem like
| this:
|
| def loadfiles(filelist):
| if not isinstance(filelist, list):
| filelist = filelist,

Any what if 'filelist' is any iterable other than a string or list? Your
code is broken, and unnecessarily so. So I would call the parameter
'files' and test for isinstance(files, str) #or basestring. And wrap if it
is.

| for filename in filelist:
| f = open(filename,'r')
| #do interesting stuff with file, etc...
|
| ..and it's been working very well.
|
| Cheers,
| -Basilisk96
|
| --
| http://mail.python.org/mailman/listinfo/python-list
|
 
B

Basilisk96

Terry Reedy said:
Any what if 'filelist' is any iterable other than a string or list? Your
code is broken, and unnecessarily so. So I would call the parameter
'files' and test for isinstance(files, str) #or basestring. And wrap if it
is.

Can you give an example of such an iterable (other than a tuple)? I'd
certainly like to fix my 'fix' to work for a more general case.

Regards,
-Basilisk96
 
M

Marc 'BlackJack' Rintsch

Basilisk96 said:
Can you give an example of such an iterable (other than a tuple)? I'd
certainly like to fix my 'fix' to work for a more general case.

def iter_filenames(filename):
lines = open(filename, 'r')
for line in lines:
yield line.rstrip()
lines.close()

filenames = iter_filenames('files.txt')

Now `filenames` is an iterable over strings representing file names but
it's not a `list`. And it's easy to come up with iterables over strings
that produce the data themselves, for example by attaching a counter to a
basename, or extracting the names from XML files, fetching them from a
database etc.

Ciao,
Marc 'BlackJack' Rintsch
 
T

Terry Reedy

| > Any what if 'filelist' is any iterable other than a string or list?
Your
| > code is broken, and unnecessarily so. So I would call the parameter
| > 'files' and test for isinstance(files, str) #or basestring. And wrap
if it
| > is.
|
| Can you give an example of such an iterable (other than a tuple)?

Tuple was the first thing I thought of, and one will break the list test.
The next would be an iterator that walks a file hierarchy spitting out the
names of non-directory files, or all files with a certain extension, or all
files with a certain owner, or timestamp characteristic.

| I'd certainly like to fix my 'fix' to work for a more general case.

As I said, I think it as simple as changing 'not list' to 'is string'.

tjr
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top