[issue33098] add implicit conversion for random.choice() on a dict

2018-03-19 Thread Aristide Grange

Aristide Grange  added the comment:

My bad... For my reference to Python 2, I relied on my memory only, which 
starts to vanish. Really sorry about that. Yes, `random.choice(d)` (mostly) 
fails in Python 2 too, with an error message that I better understand after 
reading your explanation.

So, in Python 2/3, when `random.choice()` is applied to a dictionary, it draws 
a random integer i in [0, len(d)[ and tries to return the _value_ `d[i]`. It's 
quite unexpected, for me at last. According to the doc:

random.choice(seq)
Return a random element from the non-empty sequence seq. If seq is empty, 
raises IndexError.

In Python 3, evaluating `choice(d.keys())` raises "TypeError: 'dict_keys' 
object does not support indexing". Shouldn't `choice(d)` _always_ fail with the 
same error message? I am not sure to see any legitimate use for the current 
behavior.

With regard to the repeated refusal to hide the fact that `choice`-ing among 
the keys of a dictionary is a linear operation, I can understand this decision. 
The general interest does not necessary align with that of an algorithmic 
teacher which only uses Python as a support language for introducing students 
to basic / transversal datatypes such as lists, arrays, dictionaries, sets, and 
prefers to avoid speaking of `dict_keys` and other Python's niceties...

Anyway, thanks a lot for your detailed and patient answer.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33098] add implicit conversion for random.choice() on a dict

2018-03-18 Thread Tim Peters

Tim Peters  added the comment:

This won't be changed.  The dict type doesn't support efficient random choice 
(neither do sets, by the way), and it's been repeatedly decided that it would 
do a disservice to users to hide that.  As you know, you can materialize the 
keys in a list (or tuple) first if you _want_ to pay that cost.  Otherwise you 
should use a different data structure.

Note that there's really no differnce between Pythons 2 and 3 here.  If you 
_happen_ to have a dict that uses little integers as keys, then it can _appear_ 
to work, when a random integer picked from range(len(the_dict)) happens to be 
one of the keys.  But then you get back the associated dict value, not the key. 
 For example, here under Python 2.7.11:

>>> import random
>>> random.choice({0: "a", 1: "b"})
'b'
>>> random.choice({0: "a", 1: "b"})
'b'
>>> random.choice({0: "a", 1: "b"})
'a'

But if the keys don't happen to be little integers, it always fails:

>>> random.choice({"a": 1, "b": 2})
Traceback (most recent call last):
  File "", line 1, in 
  File "C:\Python27\lib\random.py", line 275, in choice
return seq[int(self.random() * len(seq))]  # raises IndexError if seq is 
empty
KeyError: 1

--
nosy: +tim.peters
resolution:  -> wont fix
stage:  -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue33098] add implicit conversion for random.choice() on a dict

2018-03-18 Thread Aristide Grange

New submission from Aristide Grange :

In Python 3, the expression:

```python
random.choice(d)
```

where `d` is a `dict`, raises this error:

```
~/anaconda3/lib/python3.6/random.py in choice(self, seq)
256 except ValueError:
257 raise IndexError('Cannot choose from an empty sequence') 
from None
--> 258 return seq[i]
259 
260 def shuffle(self, x, random=None):

KeyError: 2
```

Converting `d` into a list restores the Python 2's behavior:

```python
random.choice(list(d))
```

I am aware that the keys of a dict have now their own type. But IMHO the error 
message is rather uninformative, and above all, couldn't this conversion be 
made implicitely under the hood?

--
messages: 314062
nosy: Aristide Grange
priority: normal
severity: normal
status: open
title: add implicit conversion for random.choice() on a dict
type: enhancement
versions: Python 3.4

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com