Currently during assignment, when target list is a comma-separated list of
targets (*without "starred" target*) the rule is that the object (rhs) must
be an iterable with the same number of items as there are targets in the
target list. That is, no check is performed on the number of targets
present, and if something goes wrong the ValueError is raised. To show
this on simple example:
>>> from itertools import count, islice
>>> it = count()
>>> x, y = it
Here the count was advanced two times but assignment did not happen. I
found that in some cases it is too much restricting that rhs must have the
same number of items as targets. It is proposed that if the rhs is a
generator or an iterator (better some object that yields values on demand),
the assignmenet should be lazy and dependent on the number of targets. I
find this feature to be very convenient for interactive use, while it
remains readable, expected, and expressed in a more compact code.
There are some Pros:
1. No overhead
2. Readable and not so verbose code
3. Optimized case for x,y,*z = iterator
4. Clear way to assign values partially from infinite generators.
1. A special case of how assignment works
2. As with any implicit behavior, hard-to-find bugs
There several cases with "undefined" behavior:
1. Because the items are assigned, from left to right to the corresponding
targets, should rhs see side effects during assignment or not?
2. Should this work only for generators or for any iterators?
3. Is it Pythonic to distinguish what is on the rhs during assignment, or
it contradicts with duck typing (goose typing)?
In many cases it is possible to do this right now, but in too verbose way:
>>> x, y = islice(gen(), 2)
But it seems for me that:
>>> x, y = gen()
Looks the same, easy to follow and not so verbose. Another case, which is a
pitfall, but will be possible:
>>> x, y = iter([0,1,2,3,4]) # Now it is Ok
>>> x, y = [0,1,2,3,4] # raises ValueError
With kind regards, -gdg
In 3.7 I have removed an old-deprecated plistlib.Dict.  Actually it
already was deprecated when the plistlib module was added to the regular
stdlib in Python 2.6.
This is a dict subclass which allows to access items as attributes.
d = plistlib.Dict()
d['a'] = 1
assert d.a == 1
d.b = 2
assert d['b'] == 2
Raymond noticed that that capability seemed nice to have.
What do you think about reviving this type as general purpose type in
collections or types? Perhaps it can be convenient for working with
JSON, plists, configuration files, databases and in other cases that
need a dict with string keys.
If reintroduce it, there are open questions.
1. The name of the type.
2. The location of the type. collections or types? Or other variants?
3. How it will collaborate with OrderedDict, defaultdict, etc?
4. Should it be a dict subclass, or a mixin, or a proxy? Or add several
On Wed, Nov 29, 2017 at 5:46 AM, Alon Snir <AlonSnir(a)hotmail.com> wrote:
> I would like to mention that the issue of assignment to a target list, is also relevant to the case of elementwise assignment to a mutable sequence (e.g. lists and arrays). Here as well, the rhs of the assignment statement states the number of elements to be assigned. Consequently, the following example will get into infinite loop:
>>>> from itertools import count
>>>> A = 
>>>> A[:] = count()
> Writing "A[:2] = count()" will cause the same result.
> Here as well, it is currently safer to use islice if the rhs is a generator or an iterator. e.g.:
>>>> it = count()
>>>> A[:] = islice(it,2)
> In my opinion, it is be better to devise a solution that could be applied in both cases. Maybe a new kind of assignment operator that will be dedicated to this kind of assignment. i.e. elementwise assignment with restriction on the number of elements to be assigned, based on the length of the lhs object (or the number of targets in the target list).
Hmm. The trouble is that slice assignment doesn't have a fixed number of targets. If you say "x, y = spam", there's a clear indication that 'spam' needs to provide exactly two values; but "A[:] = spam" could have any number of values, and it'll expand or shrink the list accordingly.
Rhodri James wrote:
Flatly, no. It is better not to ask for things you don't want in the first place, in this case the infinite sequence.
Still, don't let me discourage you from working on this. If you can define how such an assignment would work, or even the length of A[:] as an assignment target, I'm not going to dismiss it out of hand.
The idea is to define an alternative assignment rule, that is to assign exactly as many elements as the current length of the lhs object (without expanding or shrinking it). Suppose "?=" is the operator for the alternative assignment rule; A=[None]*2; and "iterator" is any iterator (finite or infinite). In this case, the following code:
>>> A ?= iterator
would behave like this:
>>> A[:] = islice(iterator, 2) # where 2 is the length of A
And as suggested earlier for the case of assignment to a target list, the following code:
>>> x, y ?= iterator
would behave like this:
>>> x, y = islice(iterator, 2) # where 2 is the number of targets
Regarding the length issue:
Is there any difficulty in finding the length of a sliced sequence? After all, the range object has a len method. Therefore, the length of A[s] (where s is a slice object) could be evaluated as follows:
As explained in PEP 560, creation of Generic subclasses is much slower (~7x on my machine).
My guess is that a limited number of applications actually need Generic classes at "production" runtime (i.e. when not under analysis of mypy or IDE).
I propose a special class that will alias typing.Generic whenever typing.TYPE_CHECKING == True and a no-op stub otherwise.