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.
On Wed, 08 Sep 2004 19:27:38 -0400, flacco wrote:
[color=blue]
>
> 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.[/color]
Jeremy Bowers wrote:[color=blue]
> On Wed, 08 Sep 2004 19:27:38 -0400, flacco wrote:
>[color=green]
>>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.[/color]
>
> In what way does
>
> for obj in container:
>
> not meet your needs?[/color]
i always want obj to be the value. dicts, for example, yield keys
instead of values (i think?)...
On Wed, 08 Sep 2004 20:35:56 -0400, flacco wrote:[color=blue]
> i always want obj to be the value. dicts, for example, yield keys
> instead of values (i think?)...[/color]
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(iter able, dict):
return iterable.iterva lues()
# Whatever other special cases you may need
return iter(iterable)
for obj in values(containe r):
# 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 IterateGivesMeV alues(dict):
# It is quite likely your domain will give you a better
# name :-)
def __iter__(self):
return self.itervalues ()
igmv = IterateGivesMeV alues()
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.
[flacco][color=blue]
> 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.[/color]
try:
it = obj.itervalues( )
except AttributeError:
it = iter(obj)
for value in it:
. . .
"flacco" <flacco002@spam badTwilight-systems.com> wrote in message
news:10jv9ae988 bbnb7@corp.supe rnews.com...[color=blue]
> Jeremy Bowers wrote:[color=green]
>> On Wed, 08 Sep 2004 19:27:38 -0400, flacco wrote:
>>[color=darkred]
>>>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.[/color]
>>
>> In what way does
>>
>> for obj in container:
>>
>> not meet your needs?[/color]
>
> i always want obj to be the value. dicts, for example, yield keys
> instead of values (i think?)...[/color]
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.
flacco <flacco002@spam badTwilight-systems.com> wrote:
...[color=blue][color=green]
> > In what way does
> >
> > for obj in container:
> >
> > not meet your needs?[/color]
>
> i always want obj to be the value. dicts, for example, yield keys
> instead of values (i think?)...[/color]
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!).
def viter(container ):
"""Iterate over values of a container"""
if hasattr(contain er, "itervalues "):
return container.iterv alues()
return iter(container)
Comment