Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #99431
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | Re: list slice and generators |
| Date | 2015-11-25 11:07 +0100 |
| Organization | None |
| Message-ID | <mailman.65.1448446043.20593.python-list@python.org> (permalink) |
| References | <5654D8CE.2020105@gmail.com> |
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
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]
or
metrics = (converter(x.metric(name)) for x in self._server_per_proc)
metrics = [x for x in metrics if x is not None]
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
> return calculate(name, metrics)
>
>
> def calculate(name, metrics):
> if not metrics:
> return None
>
> if name in METRICS_SUM:
> return sum(metrics)
> elif name in METRICS_AVG:
# writing a function that calculates the average without
# materialising the list left as an exercise ;)
metrics = list(metrics)
> return int(sum(metrics)/len(metrics))
> else:
> raise ValueError("Unknown type of calculation for
> {}".format(name))
>
>
> def converter(value):
> try:
> return int(float(value))
> except ValueError:
> return value.strip() or None
> except TypeError:
> return None
Disclaimer: all code untested.
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
Re: list slice and generators Peter Otten <__peter__@web.de> - 2015-11-25 11:07 +0100
csiph-web