Thank you in advance, D.
key, val = next(myDict.items())
Cheers,
Chris
Unfortunately, it doesn't work, it turn out to be dict_items:
>>> next({1:2}.items())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: dict_items object is not an iterator
>>> dir({1:2}.items())
['__and__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__ne__', '__new__', '__or__', '__rand__', '__reduce__',
'__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__',
'__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__',
'__xor__', 'isdisjoint']
Recognizing that if myDict is empty then this will raise StopIteration
instead of KeyError.
key, val = next(iter(myDict.items()))
http://docs.python.org/py3k/library/stdtypes.html#dictionary-view-objects
HTH,
Rob
So call iter() on it first:
next(iter(myDict.items()))
key, val = list(myDict.items())[0]
--
nirinA
Which is becoming less elegant. Seems to me that View objects should be
directly iterable, but then I don't really understand the motivation
behind them or what greatness is facilitated by having them.
Anybody care to chime in with their usage of this construct?
~Ethan~
That's not even the worst of it. If the dict is empty, then the code
above will raise a StopIteration, which must be caught locally since
if it propagates it could be swallowed by a generator. So a full
recipe should really look more like this:
try:
first_item = next(iter(my_dict.items()))
except StopIteration:
raise ValueError("empty dict")
> Seems to me that View objects should be directly iterable
They are. They're just not directly nextable because they're treated
as dependent collections, not iterators.
> but then I don't really understand the motivation behind them or what greatness is facilitated by having them.
>
> Anybody care to chime in with their usage of this construct?
You should start with PEP 3106. The main idea is that dict.keys() and
dict.items() can be treated as frozensets, while still being more
lightweight than lists. That lets you do nifty things like "a.keys()
== b.keys()" which, if a and b are Python 3 dicts, will tell you
whether they contain the same keys.
Whether anybody actually uses this, I have no idea.
If you're doing this sort of thing a lot you can make
a little helper function:
def first(x):
return next(iter(x))
then you get to say
first(myDict.items())
--
Greg
... and get a StopIteration if the dict is empty.
If you do
def first(x, default=None):
for i in x:
return i
return default
you might have an alternative approach to do so.
Thomas
Cool, thanks.
~Ethan~
If your use case allows the item to be removed, then use:
key, val = myDict.popitem()
Otherwise, use:
key, val = next(iter(MyDict.items()))
The latter is nice because next() allows you to supply a default
argument in case the dictionary is emtpy:
key, val = next(iter(MyDict.items()), (None, None))
Raymond
---------
follow my tips and recipes on twitter: @raymondh