Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Peter Otten <__peter__@web.de> Newsgroups: comp.lang.python Subject: Re: list slice and generators Date: Wed, 25 Nov 2015 11:07:08 +0100 Organization: None Lines: 71 Message-ID: References: <5654D8CE.2020105@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7Bit X-Trace: news.uni-berlin.de arveMdrQReCjW62mfSo1WQznh2EzzoQaWwsCzrc9zTbg== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'exercise': 0.03; 'elif': 0.04; 'executed': 0.07; 'none)': 0.07; 'valueerror:': 0.07; "'0',": 0.09; 'generators': 0.09; 'metrics': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'typeerror:': 0.09; 'bug': 0.10; 'def': 0.13; 'intermediate': 0.15; 'assignment.': 0.16; 'calculates': 0.16; 'generators.': 0.16; 'none]': 0.16; 'received:80.91.229.3': 0.16; 'received:dip0.t-ipconnect.de': 0.16; 'received:io': 0.16; 'received:plane.gmane.org': 0.16; 'received:psf.io': 0.16; 'received:t-ipconnect.de': 0.16; 'twice.': 0.16; 'wrote:': 0.16; 'try:': 0.18; 'bit': 0.23; 'elements': 0.23; 'header:User- Agent:1': 0.26; 'subject:list': 0.26; 'header:X-Complaints-To:1': 0.26; 'least': 0.27; 'function': 0.28; 'skip:( 20': 0.28; 'python2.7': 0.29; 'raise': 0.29; 'code': 0.30; 'skip:[ 10': 0.31; 'problem': 0.33; 'avoiding': 0.33; 'except': 0.34; 'list': 0.34; 'replace': 0.35; 'item': 0.35; 'skip:i 20': 0.36; 'there': 0.36; 'possible': 0.36; 'skip:{ 10': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'received:org': 0.37; 'list.': 0.37; 'doing': 0.38; 'hi,': 0.38; 'to:addr:python.org': 0.40; 'received:de': 0.40; 'avoid': 0.61; 'side': 0.62; 'back': 0.62; 'skip:n 10': 0.62; 'goal': 0.64; 'disclaimer:': 0.67; 'dangerous': 0.70; 'average': 0.93 X-Injected-Via-Gmane: http://gmane.org/ X-Gmane-NNTP-Posting-Host: p57bd9ab0.dip0.t-ipconnect.de User-Agent: KNode/4.13.3 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:99431 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.