Python 3 dict question

D

dmitrey

hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
do_something
break
but maybe there is any better way?

Thank you in advance, D.
 
C

Chris Rebert

hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
  do_something
  break
but maybe there is any better way?

key, val = next(myDict.items())

Cheers,
Chris
 
D

dmitrey

hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
  do_something
  break
but maybe there is any better way?

key, val = next(myDict.items())

Cheers,
Chris

Unfortunately, it doesn't work, it turn out to be dict_items:Traceback (most recent call last):
['__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']
 
I

Ian Kelly

hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
  do_something
  break
but maybe there is any better way?

key, val = next(myDict.items())

Recognizing that if myDict is empty then this will raise StopIteration
instead of KeyError.
 
R

Rob Wolfe

dmitrey said:
hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
do_something
break
but maybe there is any better way?

key, val = next(iter(myDict.items()))

http://docs.python.org/py3k/library/stdtypes.html#dictionary-view-objects

HTH,
Rob
 
I

Ian Kelly

Unfortunately, it doesn't work, it turn out to be dict_items:
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: dict_items object is not an iterator

So call iter() on it first:

next(iter(myDict.items()))
 
N

nirinA raseliarison

[dmitrey]
hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
do_something
break
but maybe there is any better way?

key, val = list(myDict.items())[0]
 
E

Ethan Furman

Ian said:
So call iter() on it first:

next(iter(myDict.items()))

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~
 
I

Ian Kelly

Which is becoming less elegant.

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.
 
G

Gregory Ewing

Ethan said:
Which is becoming less elegant.

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())
 
T

Thomas Rachel

Am 07.05.2011 11:09, schrieb Gregory Ewing:
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())

.... 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
 
E

Ethan Furman

Ian said:
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.

Cool, thanks.

~Ethan~
 
R

Raymond Hettinger

hi all,
suppose I have Python dict myDict and I know it's not empty.
I have to get any (key, value) pair from the dict (no matter which
one) and perform some operation.
In Python 2 I used mere
key, val = myDict.items()[0]
but in Python 3 myDict.items() return iterator.
Of course, I could use
for key, val in myDict.items():
   do_something
   break
but maybe there is any better way?

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
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top