Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #51161 > unrolled thread
| Started by | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| First post | 2013-07-24 11:31 -0700 |
| Last post | 2013-07-25 18:25 +0200 |
| Articles | 8 — 6 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Python 3: dict & dict.keys() Ethan Furman <ethan@stoneleaf.us> - 2013-07-24 11:31 -0700
Re: Python 3: dict & dict.keys() alex23 <wuwei23@gmail.com> - 2013-07-25 16:01 +1000
Re: Python 3: dict & dict.keys() Ethan Furman <ethan@stoneleaf.us> - 2013-07-25 06:47 -0700
Re: Python 3: dict & dict.keys() Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-25 07:04 +0000
Re: Python 3: dict & dict.keys() Chris Angelico <rosuav@gmail.com> - 2013-07-25 18:02 +1000
Re: Python 3: dict & dict.keys() Peter Otten <__peter__@web.de> - 2013-07-25 10:13 +0200
Re: Python 3: dict & dict.keys() Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-25 09:53 -0600
Re: Python 3: dict & dict.keys() Peter Otten <__peter__@web.de> - 2013-07-25 18:25 +0200
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-24 11:31 -0700 |
| Subject | Re: Python 3: dict & dict.keys() |
| Message-ID | <mailman.5061.1374692206.3114.python-list@python.org> |
On 07/24/2013 10:23 AM, Stefan Behnel wrote: > Peter Otten, 24.07.2013 08:23: >> Ethan Furman wrote: >>> >>> So, my question boils down to: in Python 3 how is dict.keys() different >>> from dict? What are the use cases? >> >> To me it looks like views are a solution waiting for a problem. > > They reduce the API overhead. Previously, you needed values() and > itervalues(), with values() being not more than a special case of what > itervalues() provides anyway. Now it's just one method that gives you > everything. It simply has corrected the tradeoff from two special purpose > APIs to one general purpose API, that's all. I started this thread for two reasons: 1) Increase awareness that using `list(dict)` is a cross-version replacement for `dict.keys()` 2) Hopefully learn something about when a view is useful. So far #2 is pretty much a failure. Only one use-case so far (and it feels pretty rare). But hey, I have learned that while some set operations are allowed (&, ^, |, .isdisjoint()), others are not (.remove(), .discard(), .union(), etc.). The old .keys(), .values(), and .items() (and their .iter...() variations) did something commonly useful. Of what common use are these views? -- ~Ethan~
[toc] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2013-07-25 16:01 +1000 |
| Message-ID | <ksqeju$5s7$1@dont-email.me> |
| In reply to | #51161 |
On 25/07/2013 4:31 AM, Ethan Furman wrote: > 2) Hopefully learn something about when a view is useful. I haven't seeen this mentioned - forgive me if it's a repeat - but views are constant references to whichever set they represent. Python 2.7: >>> dd = dict(a=1,b=2,c=3) >>> keys = dd.keys() >>> 'a' in keys True >>> dd['d'] = 4 >>> 'd' in keys False Python 3.3: >>> dd = dict(a=1,b=2,c=3) >>> keys = dd.keys() >>> 'a' in keys True >>> dd['d'] = 4 >>> 'd' in keys True If part of my code is only interested in what keys or values are present, it doesn't need to be given a reference to the full dictionary, just to whichever view it cares about.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-25 06:47 -0700 |
| Message-ID | <mailman.5102.1374762804.3114.python-list@python.org> |
| In reply to | #51192 |
On 07/24/2013 11:01 PM, alex23 wrote: > On 25/07/2013 4:31 AM, Ethan Furman wrote: >> 2) Hopefully learn something about when a view is useful. > > I haven't seeen this mentioned - forgive me if it's a repeat - but views are constant references to whichever set they > represent. > > Python 2.7: > >>>> dd = dict(a=1,b=2,c=3) >>>> keys = dd.keys() >>>> 'a' in keys > True >>>> dd['d'] = 4 >>>> 'd' in keys > False > > Python 3.3: >>>> dd = dict(a=1,b=2,c=3) >>>> keys = dd.keys() >>>> 'a' in keys > True >>>> dd['d'] = 4 >>>> 'd' in keys > True > > If part of my code is only interested in what keys or values are present, it doesn't need to be given a reference to the > full dictionary, just to whichever view it cares about. In these cases why is a view better than just using the dict? Is it a safety so the you don't accidentally modify the dict? -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-07-25 07:04 +0000 |
| Message-ID | <51f0ce06$0$29971$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #51161 |
On Wed, 24 Jul 2013 11:31:58 -0700, Ethan Furman wrote: > On 07/24/2013 10:23 AM, Stefan Behnel wrote: >> Peter Otten, 24.07.2013 08:23: >>> Ethan Furman wrote: >>>> >>>> So, my question boils down to: in Python 3 how is dict.keys() >>>> different from dict? What are the use cases? >>> >>> To me it looks like views are a solution waiting for a problem. >> >> They reduce the API overhead. Previously, you needed values() and >> itervalues(), with values() being not more than a special case of what >> itervalues() provides anyway. Now it's just one method that gives you >> everything. It simply has corrected the tradeoff from two special >> purpose APIs to one general purpose API, that's all. > > I started this thread for two reasons: > > 1) Increase awareness that using `list(dict)` is a cross-version > replacement for `dict.keys()` > > 2) Hopefully learn something about when a view is useful. > > So far #2 is pretty much a failure. I don't think so. - viewkeys() can be used as a drop-in replacement for iterkeys(), provided you remember not to iterate over it a second time. Doing so actually iterates over the view, instead of failing as with the iterator. If you actually want a one-shot iterator, call iter() on the view. - viewkeys() can be used as a drop-in replacement for Python2 keys(), provided you only iterate over it once. If you want an actual list, call list() on the view. - Views support set methods which don't modify the set. If there is a non- modifying set method which is not supported, it probably should be, and somebody should raise an enhancement request in the bug tracker. If you want an actual independent set you can modify without changing the dict, call set() (or frozenset) on the view. - Views support efficient (O(1) in the case of keys) membership testing, which neither iterkeys() nor Python2 keys() does. - Views support live, read-only access to dict keys and values. > Only one use-case so far (and it > feels pretty rare). Iterating over a dict's values or items is not rare. Using a view is better than making a list-copy of the dict and iterating over the list, because it avoids copying. For one-shot iteration, there's no benefit of a view over an iterator, or vice versa, but views are useful for more than just one-shot iteration. > But hey, I have learned that while some set > operations are allowed (&, ^, |, .isdisjoint()), others are not > (.remove(), .discard(), .union(), etc.). > > The old .keys(), .values(), and .items() (and their .iter...() > variations) did something commonly useful. Of what common use are these > views? Everything that dict iteration does, dict views do, and more. So if iterkeys() is useful, then so is viewkeys(). Had viewkeys come first, iterkeys would never have been invented. Making an actual list copy of the keys (values, items) is useful, but it's not useful enough to dedicate a method (three methods) for it. Just call list() on the view (or, in the case of keys, directly on the dict). -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-07-25 18:02 +1000 |
| Message-ID | <mailman.5085.1374739334.3114.python-list@python.org> |
| In reply to | #51198 |
On Thu, Jul 25, 2013 at 5:04 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > - Views support efficient (O(1) in the case of keys) membership testing, > which neither iterkeys() nor Python2 keys() does. To save me the trouble and potential error of digging through the source code: What's the complexity of membership testing on values/items? Since you're calling it "efficient" it must be better than O(n) which the list form would be, yet it isn't O(1) or you wouldn't have qualified "in the case of keys". Does this mean membership testing of the values and items views is O(log n) in some way, eg a binary search? ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-07-25 10:13 +0200 |
| Message-ID | <mailman.5086.1374740010.3114.python-list@python.org> |
| In reply to | #51198 |
Chris Angelico wrote: > On Thu, Jul 25, 2013 at 5:04 PM, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: >> - Views support efficient (O(1) in the case of keys) membership testing, >> which neither iterkeys() nor Python2 keys() does. > > To save me the trouble and potential error of digging through the > source code: What's the complexity of membership testing on > values/items? Since you're calling it "efficient" it must be better > than O(n) which the list form would be, yet it isn't O(1) or you > wouldn't have qualified "in the case of keys". Does this mean > membership testing of the values and items views is O(log n) in some > way, eg a binary search? keys() and items() is O(1); both look up the key in the dictionary and items() then proceeds to compare the value. values() is O(n).
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-07-25 09:53 -0600 |
| Message-ID | <mailman.5107.1374767657.3114.python-list@python.org> |
| In reply to | #51198 |
On Thu, Jul 25, 2013 at 2:13 AM, Peter Otten <__peter__@web.de> wrote: > Chris Angelico wrote: > >> On Thu, Jul 25, 2013 at 5:04 PM, Steven D'Aprano >> <steve+comp.lang.python@pearwood.info> wrote: >>> - Views support efficient (O(1) in the case of keys) membership testing, >>> which neither iterkeys() nor Python2 keys() does. >> >> To save me the trouble and potential error of digging through the >> source code: What's the complexity of membership testing on >> values/items? Since you're calling it "efficient" it must be better >> than O(n) which the list form would be, yet it isn't O(1) or you >> wouldn't have qualified "in the case of keys". Does this mean >> membership testing of the values and items views is O(log n) in some >> way, eg a binary search? > > keys() and items() is O(1); both look up the key in the dictionary and > items() then proceeds to compare the value. values() is O(n). 3.x values() is O(n) but avoids the unnecessary step of copying all the values in the dict that you get when performing the same operation using 2.x values(). Hence, although the asymptotic complexity is the same, it's still more efficient.
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-07-25 18:25 +0200 |
| Message-ID | <mailman.5111.1374769510.3114.python-list@python.org> |
| In reply to | #51198 |
Ian Kelly wrote: > On Thu, Jul 25, 2013 at 2:13 AM, Peter Otten <__peter__@web.de> wrote: >> Chris Angelico wrote: >> >>> On Thu, Jul 25, 2013 at 5:04 PM, Steven D'Aprano >>> <steve+comp.lang.python@pearwood.info> wrote: >>>> - Views support efficient (O(1) in the case of keys) membership >>>> testing, which neither iterkeys() nor Python2 keys() does. >>> >>> To save me the trouble and potential error of digging through the >>> source code: What's the complexity of membership testing on >>> values/items? Since you're calling it "efficient" it must be better >>> than O(n) which the list form would be, yet it isn't O(1) or you >>> wouldn't have qualified "in the case of keys". Does this mean >>> membership testing of the values and items views is O(log n) in some >>> way, eg a binary search? >> >> keys() and items() is O(1); both look up the key in the dictionary and >> items() then proceeds to compare the value. values() is O(n). > > 3.x values() is O(n) but avoids the unnecessary step of copying all the > values in the dict that you get when performing the same operation > using 2.x values(). Hence, although the asymptotic complexity is the > same, it's still more efficient. In Python 2 the prudent pythonista used itervalues() to avoid unnecessary intermediate list...
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web