list slice and generators
Pavlos Parissis
pavlos.parissis at gmail.com
Wed Nov 25 15:43:20 EST 2015
On 25/11/2015 11:07 πμ, Peter Otten wrote:
> Pavlos Parissis wrote:
>
>> Hi,
>>
>> Do you see any possible dangerous hidden bug in the below code(using
>> python2.7 and python3.4)?
>>
>> My goal is to avoid go through the metrics list twice. But, I don't
>> know if there will be a problem with doing in place replace of list
>> elements using 2 generators.
>>
>> # metrics = ['', '0', '10'....]
>> metrics = [x.metric(name) for x in self._server_per_proc]
>> metrics[:] = (converter(x) for x in metrics)
>> metrics[:] = (x for x in metrics if x is not None)
>
> Both generators are executed immediately, and the right side is always
> evaluated before the the slice assignment. Try
>
This is what I was vaguely remembering, thanks for the confirmation.
> metrics = (x.metric(name) for x in self._server_per_proc)
> metrics = (converter(x) for x in metrics)
> metrics = [x for x in metrics if x is not None]
>
I see you prefer to bind the result of the evaluation to the same
variable. I learned (the hard way) that it could lead to problems where::
In [1]: a = [1, 2, 3]
In [2]: b = a
In [3]: a == b, a is b
Out[3]: (True, True)
In [4]: a = (x for x in a if x >1)
In [5]: a == b, a is b
Out[5]: (False, False)
In [6]: a
Out[6]: <generator object <genexpr> at 0x7f7f8b7400d8>
In [7]: list(a)
Out[7]: [2, 3]
In [8]: a = [1, 2, 3]
In [9]: b = a
In [10]: a == b, a is b
Out[10]: (True, True)
In [11]: a = [x for x in a if x >1]
In [12]: a == b, a is b
Out[12]: (False, False)
In [13]: a
Out[13]: [2, 3]
In [14]: b
Out[14]: [1, 2, 3]
Thus, I always use slice assignment, even when above case isn't applied.
> or
>
> metrics = (converter(x.metric(name)) for x in self._server_per_proc)
> metrics = [x for x in metrics if x is not None]
>
I should do the above.
> to get down to one intermediate list. Avoiding the last one is a bit tricky:
>
> metrics = (converter(x.metric(name)) for x in self._server_per_proc)
> metrics = (x for x in metrics if x is not None)
> try:
> # if there is at least one item the generator is not empty
> first = next(metrics)
> except StopIteration:
> metrics = ()
> else:
> # put the first item back in
> metrics = itertools.chain([first], metrics)
> assert metrics
>
Tricky, indeed
Thanks for your time and effort to answer my question, it is very
much appreciated.
Cheers,
Pavlos
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-list/attachments/20151125/e39fa24a/attachment.sig>
More information about the Python-list
mailing list