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
signature.asc
Description: OpenPGP digital signature
-- https://mail.python.org/mailman/listinfo/python-list