container-indepentent iteration code ?

F

flacco

is there a way to iterate over the *values* in a list/dict/whatever,
regardless of whether it's a list, dict, or whatever? ie, the iteration
code will not know beforehand what kind of container it's getting.
 
J

Jeremy Bowers

is there a way to iterate over the *values* in a list/dict/whatever,
regardless of whether it's a list, dict, or whatever? ie, the iteration
code will not know beforehand what kind of container it's getting.

In what way does

for obj in container:

not meet your needs?
 
F

flacco

Jeremy said:
In what way does

for obj in container:

not meet your needs?

i always want obj to be the value. dicts, for example, yield keys
instead of values (i think?)...
 
J

Jeremy Bowers

i always want obj to be the value. dicts, for example, yield keys
instead of values (i think?)...

Ah, that clarifies it for me. "Values" is a bit of an overloaded term. :)

The problem you're running into here is that the "standard iterator" kind
of "defines" the "values" the container has. That's the only idea of
"default set of values in a container" that Python is going to understand.

Thus, since the fundamental issue is a disagreement between you and Python
about what constitutes a "value" out of a dict (and as the human in this
transaction you are the right one :) ), I don't see any way to avoid
explaining your idea to Python. You can make it convenient:

def values(iterable):
if isinstance(iterable, dict):
return iterable.itervalues()
# Whatever other special cases you may need
return iter(iterable)

for obj in values(container):
# etc.

but there's no switch or anything that will do what you want. Sorry.
You're always going to have to explain what you mean by "whatever" to
Python.

Stepping up one meta-level, another possibility that you may consider is
creating some container classes that match whatever your heterogenous
containment needs are, then you can make *those* containers work naturally
without the function I showed above. Without knowing more about your
problem, I can't know if that is better in general.

Consider this:

class IterateGivesMeValues(dict):
# It is quite likely your domain will give you a better
# name :)
def __iter__(self):
return self.itervalues()

igmv = IterateGivesMeValues()
igmv["key"] = "value"
for i in igmv:
print i

will print "value" instead of "dict". If you build your structures out of
such objects your life may, or may not, be easier.
 
R

Raymond Hettinger

[flacco]
is there a way to iterate over the *values* in a list/dict/whatever,
regardless of whether it's a list, dict, or whatever? ie, the iteration
code will not know beforehand what kind of container it's getting.

try:
it = obj.itervalues()
except AttributeError:
it = iter(obj)
for value in it:
. . .


Raymond Hettinger
 
T

Terry Reedy

flacco said:
i always want obj to be the value. dicts, for example, yield keys
instead of values (i think?)...

When iterators were introduced, there was discussion of whether

for x in somedict:

should iterate over dict.keys(), dict.values(), dict.items(), or continue
to be illegal. dict.keys() won as being most useful because most commonly
needed. Iterating over values or items continues to have to be explicit.

Terry J. Reedy
 
A

Alex Martelli

flacco said:
i always want obj to be the value. dicts, for example, yield keys
instead of values (i think?)...

Yep, as Jeremy explained, iter(container) [[implicitly called by the for
statement]] lets the container decide which are the container's *items*.

If you don't like the way a container defines what its items are for
default iteration purposes you need to tweak things in the cases you
don't like (another example might be files: their items are lines --
what if you want characters, or blocks of 37 characters, or ...? no way
Python can possibly guess without explicit action on your part!).


Alex
 
J

Jeff Epler

def viter(container):
"""Iterate over values of a container"""
if hasattr(container, "itervalues"):
return container.itervalues()
return iter(container)

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFBQF6cJd01MZaTXX0RAgt3AJ9dHLhksoNnLnASjxYy6HWoQvzcQgCeIupe
ZH8D81nH8HYzqfh1x4iPlP0=
=oSx2
-----END PGP SIGNATURE-----
 

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
474,206
Messages
2,571,069
Members
47,675
Latest member
RollandKna

Latest Threads

Top