Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #101551 > unrolled thread
| Started by | Nick Mellor <thebalancepro@gmail.com> |
|---|---|
| First post | 2016-01-12 08:50 -0800 |
| Last post | 2016-01-13 15:58 +0000 |
| Articles | 18 — 11 participants |
Back to article view | Back to comp.lang.python
subscripting Python 3 dicts/getting the only value in a Python 3 dict Nick Mellor <thebalancepro@gmail.com> - 2016-01-12 08:50 -0800
RE: subscripting Python 3 dicts/getting the only value in a Python 3 dict Emanuel Barry <vgr255@live.ca> - 2016-01-12 12:00 -0500
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Chris Angelico <rosuav@gmail.com> - 2016-01-13 04:06 +1100
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Terry Reedy <tjreedy@udel.edu> - 2016-01-12 12:12 -0500
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Bernardo Sulzbach <mafagafogigante@gmail.com> - 2016-01-12 15:18 -0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Peter Otten <__peter__@web.de> - 2016-01-12 18:32 +0100
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Ian Kelly <ian.g.kelly@gmail.com> - 2016-01-12 10:39 -0700
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-12 19:47 +0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Marko Rauhamaa <marko@pacujo.net> - 2016-01-12 21:42 +0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-12 22:18 +0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Peter Otten <__peter__@web.de> - 2016-01-12 19:09 +0100
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Bernardo Sulzbach <mafagafogigante@gmail.com> - 2016-01-12 16:48 -0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Peter Otten <__peter__@web.de> - 2016-01-12 19:59 +0100
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Bernardo Sulzbach <mafagafogigante@gmail.com> - 2016-01-12 17:12 -0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Steven D'Aprano <steve@pearwood.info> - 2016-01-13 12:29 +1100
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Bernardo Sulzbach <mafagafogigante@gmail.com> - 2016-01-13 13:53 -0200
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Steven D'Aprano <steve@pearwood.info> - 2016-01-13 12:23 +1100
Re: subscripting Python 3 dicts/getting the only value in a Python 3 dict Grant Edwards <invalid@invalid.invalid> - 2016-01-13 15:58 +0000
| From | Nick Mellor <thebalancepro@gmail.com> |
|---|---|
| Date | 2016-01-12 08:50 -0800 |
| Subject | subscripting Python 3 dicts/getting the only value in a Python 3 dict |
| Message-ID | <f2711b57-7b11-4fd5-8bab-a3e8581177b5@googlegroups.com> |
Hi all,
Seemingly simple problem:
There is a case in my code where I know a dictionary has only one item in it. I want to get the value of that item, whatever the key is.
In Python2 I'd write:
>>> d = {"Wilf's Cafe": 1}
>>> d.values()[0]
1
and that'd be an end to it.
In Python 3:
>>> d = {"Wilf's Cafe": 1}
>>> d.values()[0]
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'dict_values' object does not support indexing
"Wilf's Cafe"
>>> d[list(d)[0]]
1
>>> for k in d:
... value = d[k]
... break
...
>>> value
1
>>> list(d.values())[0]
1
None of this feels like the "one, and preferably only one, obvious way to do it" we all strive for. Any other ideas?
Thanks,
Nick
[toc] | [next] | [standalone]
| From | Emanuel Barry <vgr255@live.ca> |
|---|---|
| Date | 2016-01-12 12:00 -0500 |
| Message-ID | <mailman.70.1452618016.13488.python-list@python.org> |
| In reply to | #101551 |
> Hi all,
>
> Seemingly simple problem:
>
> There is a case in my code where I know a dictionary has only one item in it. I want to get the value of that item, whatever the key is.
>
> In Python2 I'd write:
>
> >>> d = {"Wilf's Cafe": 1}
> >>> d.values()[0]
> 1
The equivalent in Python 3 is `list(d.values())[0]`
> None of this feels like the "one, and preferably only one, obvious way to do it" we all strive for. Any other ideas?
If you feel like doing that, `for v in d.values(): pass` will set `v` to your value. But it's a bit cryptic, so you can probably resort to the list() alternative above :)
- Emanuel
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-01-13 04:06 +1100 |
| Message-ID | <mailman.71.1452618384.13488.python-list@python.org> |
| In reply to | #101551 |
On Wed, Jan 13, 2016 at 3:50 AM, Nick Mellor <thebalancepro@gmail.com> wrote:
> There is a case in my code where I know a dictionary has only one item in it. I want to get the value of that item, whatever the key is.
>
> In Python2 I'd write:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> 1
>
> and that'd be an end to it.
>
> In Python 3:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> Traceback (most recent call last):
> File "<input>", line 1, in <module>
> TypeError: 'dict_values' object does not support indexing
> "Wilf's Cafe"
>>>> d[list(d)[0]]
> 1
You could try:
next(iter(d.values()))
but honestly, this isn't all that common a situation, so I'm not
surprised there's no really simple and clean way to do it.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2016-01-12 12:12 -0500 |
| Message-ID | <mailman.73.1452618784.13488.python-list@python.org> |
| In reply to | #101551 |
On 1/12/2016 11:50 AM, Nick Mellor wrote:
> Hi all,
>
> Seemingly simple problem:
>
> There is a case in my code where I know a dictionary has only one item in it. I want to get the value of that item, whatever the key is.
>
> In Python2 I'd write:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> 1
>
> and that'd be an end to it.
>
> In Python 3:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> Traceback (most recent call last):
> File "<input>", line 1, in <module>
> TypeError: 'dict_values' object does not support indexing
The intended use of dict views: "Dictionary views can be iterated over
to yield their respective data, and support membership tests:"
> "Wilf's Cafe"
>>>> d[list(d)[0]]
> 1
>
>>>> for k in d:
> ... value = d[k]
> ... break
> ...
>>>> value
> 1
>
>>>> list(d.values())[0]
> 1
>
> None of this feels like the "one, and preferably only one,
> obvious way to do it" we all strive for. Any other ideas?
Using the values views at intended (as an iterable):
>>> dv = d.values()
>>> next(iter(dv))
1
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Bernardo Sulzbach <mafagafogigante@gmail.com> |
|---|---|
| Date | 2016-01-12 15:18 -0200 |
| Message-ID | <mailman.74.1452619122.13488.python-list@python.org> |
| In reply to | #101551 |
Intentions aside, next(iter(...)) seems the most pythonic you can get about this anyway. Just in case you happen not to need the dictionary anymore, d.popitem()[1] does the trick.
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2016-01-12 18:32 +0100 |
| Message-ID | <mailman.75.1452619985.13488.python-list@python.org> |
| In reply to | #101551 |
Nick Mellor wrote:
> Hi all,
>
> Seemingly simple problem:
>
> There is a case in my code where I know a dictionary has only one item in
> it. I want to get the value of that item, whatever the key is.
>
> In Python2 I'd write:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> 1
>
> and that'd be an end to it.
>
> In Python 3:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> Traceback (most recent call last):
> File "<input>", line 1, in <module>
> TypeError: 'dict_values' object does not support indexing
> "Wilf's Cafe"
>>>> d[list(d)[0]]
> 1
>
>>>> for k in d:
> ... value = d[k]
> ... break
> ...
>>>> value
> 1
>
>>>> list(d.values())[0]
> 1
>
> None of this feels like the "one, and preferably only one, obvious way to
> do it" we all strive for. Any other ideas?
If there is exactly one item you can unpack:
>>> d = {"Wilf's Cafe": 1}
>>> k, = d.values()
>>> k
1
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-01-12 10:39 -0700 |
| Message-ID | <mailman.77.1452620442.13488.python-list@python.org> |
| In reply to | #101551 |
On Tue, Jan 12, 2016 at 10:12 AM, Terry Reedy <tjreedy@udel.edu> wrote:
> Using the values views at intended (as an iterable):
>
>>>> dv = d.values()
>>>> next(iter(dv))
> 1
Good coding practice also dictates that whenever next is called, the
potential StopIteration exception must be caught unless it is clearly
intended to be propagated up to some generator. So more fully, this
should be something like:
dv = iter(d.values())
try:
next(dv)
except StopIteration:
raise IndexError("d is empty")
At which point it may be desirable to extract that into a utility function.
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-01-12 19:47 +0200 |
| Message-ID | <lf5a8oaellh.fsf@ling.helsinki.fi> |
| In reply to | #101551 |
Nick Mellor writes:
> Hi all,
>
> Seemingly simple problem:
>
> There is a case in my code where I know a dictionary has only one item
> in it. I want to get the value of that item, whatever the key is.
>
> In Python2 I'd write:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> d.values()[0]
> 1
>
> and that'd be an end to it.
>
> In Python 3:
If you are happy to give the sole value a name:
>>> shoe = dict(it=math.pi)
>>> [o] = shoe.values()
>>> o
3.141592653589793
You might be able to use * to pass the sole value to a function:
>>> print(*shoe.values())
3.141592653589793
But the most readable thing might be to have a function that extracts
the sole value by whatever means:
>>> def sole(d): [o] = d.values() ; return o
...
>>> sole(shoe)
3.141592653589793
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2016-01-12 21:42 +0200 |
| Message-ID | <87egdmd1ou.fsf@elektro.pacujo.net> |
| In reply to | #101563 |
Jussi Piitulainen <jussi.piitulainen@helsinki.fi>: > But the most readable thing might be to have a function that extracts > the sole value by whatever means: > > >>> def sole(d): [o] = d.values() ; return o > ... > >>> sole(shoe) > 3.141592653589793 In the same vein: >>> def sole(d): ... for o in d.values(): ... return o ... >>> sole(shoe) 3.141592653589793 Marko
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-01-12 22:18 +0200 |
| Message-ID | <lf537u2tuv8.fsf@ling.helsinki.fi> |
| In reply to | #101572 |
Marko Rauhamaa writes: > Jussi Piitulainen: > >> But the most readable thing might be to have a function that extracts >> the sole value by whatever means: >> >> >>> def sole(d): [o] = d.values() ; return o >> ... >> >>> sole(shoe) >> 3.141592653589793 > > In the same vein: > > >>> def sole(d): > ... for o in d.values(): > ... return o > ... > >>> sole(shoe) > 3.141592653589793 Tuple assignment has a useful side effect that all other methods present in this thread lack: it raises an exception if the number of dictionary entries is not exactly one.
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2016-01-12 19:09 +0100 |
| Message-ID | <mailman.80.1452622185.13488.python-list@python.org> |
| In reply to | #101551 |
Ian Kelly wrote:
> On Tue, Jan 12, 2016 at 10:12 AM, Terry Reedy <tjreedy@udel.edu> wrote:
>> Using the values views at intended (as an iterable):
>>
>>>>> dv = d.values()
>>>>> next(iter(dv))
>> 1
>
> Good coding practice also dictates that whenever next is called, the
> potential StopIteration exception must be caught unless it is clearly
> intended to be propagated up to some generator.
Even then you should be prepared for
https://docs.python.org/dev/whatsnew/3.5.html#pep-479-change-stopiteration-handling-inside-generators
> So more fully, this
> should be something like:
>
> dv = iter(d.values())
> try:
> next(dv)
> except StopIteration:
> raise IndexError("d is empty")
>
> At which point it may be desirable to extract that into a utility
> function.
[toc] | [prev] | [next] | [standalone]
| From | Bernardo Sulzbach <mafagafogigante@gmail.com> |
|---|---|
| Date | 2016-01-12 16:48 -0200 |
| Message-ID | <mailman.81.1452624540.13488.python-list@python.org> |
| In reply to | #101551 |
On Tue, Jan 12, 2016 at 3:32 PM, Peter Otten <__peter__@web.de> wrote:
>
> If there is exactly one item you can unpack:
>
>>>> d = {"Wilf's Cafe": 1}
>>>> k, = d.values()
>>>> k
> 1
>
I personally don't like that trailing comma, it just looks wrong
there. But this is very neat.
--
Bernardo Sulzbach
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2016-01-12 19:59 +0100 |
| Message-ID | <mailman.82.1452625185.13488.python-list@python.org> |
| In reply to | #101551 |
Bernardo Sulzbach wrote:
> On Tue, Jan 12, 2016 at 3:32 PM, Peter Otten <__peter__@web.de> wrote:
>>
>> If there is exactly one item you can unpack:
>>
>>>>> d = {"Wilf's Cafe": 1}
>>>>> k, = d.values()
>>>>> k
>> 1
>>
>
> I personally don't like that trailing comma, it just looks wrong
> there. But this is very neat.
>
[k] = d.values()
works the same. I used the tuple here to keep it consistent with all other
cases where the brackets are superfluous, like
[foo, *bar] = ...
foo, *bar = ...
etc.
[toc] | [prev] | [next] | [standalone]
| From | Bernardo Sulzbach <mafagafogigante@gmail.com> |
|---|---|
| Date | 2016-01-12 17:12 -0200 |
| Message-ID | <mailman.83.1452625998.13488.python-list@python.org> |
| In reply to | #101551 |
I saw it in another answer. next(iter(d)) is still the winner. This resembles a list just too much, making the coder's intent harder to understand. This is **very** subjective, of course.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-01-13 12:29 +1100 |
| Message-ID | <5695a86c$0$1588$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #101570 |
On Wed, 13 Jan 2016 06:12 am, Bernardo Sulzbach wrote:
> I saw it in another answer. next(iter(d)) is still the winner.
Except that doesn't return the *value*, it returns the *key*.
py> d = {'key': 'value'}
py> next(iter(d))
'key'
To get the value:
py> next(iter(d.values()))
'value'
> This resembles a list just too much, making the coder's intent harder
> to understand. This is **very** subjective, of course.
I'm sorry, I don't understand what you mean by "resembles a list"? What
does? In what way?
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Bernardo Sulzbach <mafagafogigante@gmail.com> |
|---|---|
| Date | 2016-01-13 13:53 -0200 |
| Message-ID | <mailman.109.1452700467.13488.python-list@python.org> |
| In reply to | #101582 |
On Tue, Jan 12, 2016 at 11:29 PM, Steven D'Aprano <steve@pearwood.info> wrote: > On Wed, 13 Jan 2016 06:12 am, Bernardo Sulzbach wrote: > >> I saw it in another answer. next(iter(d)) is still the winner. > > Except that doesn't return the *value*, it returns the *key*. > There is a typo, sorry. I assume that what is passed to iter is a dict_values object. >> This resembles a list just too much, making the coder's intent harder >> to understand. This is **very** subjective, of course. > > I'm sorry, I don't understand what you mean by "resembles a list"? What > does? In what way? > [a] = d.values() resembles a list too much to my eyes. -- Bernardo Sulzbach
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-01-13 12:23 +1100 |
| Message-ID | <5695a72a$0$1583$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #101551 |
On Wed, 13 Jan 2016 03:50 am, Nick Mellor wrote: > Hi all, > > Seemingly simple problem: > > There is a case in my code where I know a dictionary has only one item in > it. I want to get the value of that item, whatever the key is. [snip examples] > None of this feels like the "one, and preferably only one, obvious way to > do it" we all strive for. Any other ideas? That's because this is a somewhat weird case. A dict with only one item that you don't know the key of? Who does that? (Well, apart from you, obviously.) Three solutions: item = d.popitem()[1] # But this modifies the dict. # Use tuple rather than list for efficiency. item = tuple(d.values())[0] Probably the best solution, because it will conveniently raise an exception if your assumption that the dict has exactly one item is wrong: item, = d.values() # Note the comma after "item". The comma turns the assignment into sequence unpacking. Normally we would write something like this: a, b, c, d = four_items but you can unpack a sequence of one item too. If you really want to make it obvious that the comma isn't a typo: (item,) = d.values() -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Grant Edwards <invalid@invalid.invalid> |
|---|---|
| Date | 2016-01-13 15:58 +0000 |
| Message-ID | <n75s6v$n1e$1@reader1.panix.com> |
| In reply to | #101580 |
On 2016-01-13, Steven D'Aprano <steve@pearwood.info> wrote:
> Probably the best solution, because it will conveniently raise an exception
> if your assumption that the dict has exactly one item is wrong:
>
> item, = d.values() # Note the comma after "item".
[...]
> but you can unpack a sequence of one item too. If you really want to make it
> obvious that the comma isn't a typo:
>
> (item,) = d.values()
If it were I, I'd definitely do the later. I used to do it the first
way, but I often times would not notice the comma later when
maintaining the code and end up wasting an embarassing amount of time
when what should have been an easy, trivial change broke.
--
Grant Edwards grant.b.edwards Yow! It was a JOKE!!
at Get it?? I was receiving
gmail.com messages from DAVID
LETTERMAN!! !
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web