Re: Is there a better way? [combining f-string, thousands separator, right align]
On 26/08/24 23:00, Dan Sommers via Python-list wrote: On 2024-08-26 at 20:42:32 +1200, dn via Python-list wrote: and if we really want to go over-board: RIGHT_JUSTIFIED = ">" THOUSANDS_SEPARATOR = "," s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}" or (better) because right-justification is the default for numbers: s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}" To the extreme that if your user keeps fiddling with presentations (none ever do, do they?), all settings to do with s_format could be added to a config/environment file, and thus be even further separated from program-logic! And then you'll need a parser, many of whose Unique Challenges™ aren't even apparent until you start parsing files from actual users, and you'll still need some sort of fallback in the code anyway for the case that s_format can't be parsed (for whatever reason). Isn't a config file what just caused the global CrowdStrike outage? ;-) That said, I understand that report generators are a thing, not to mention RPG (https://en.wikipedia.org/wiki/IBM_RPG). Okay, sorry; I'll just crawl back into the hole from whence I came. Not at all. Please continue to question/ask/suggest! This is a valid point. There are costs and benefits (trade-offs) to all decisions! That said, writing one's own parser would become a veritable can of worms/rabbit hole. Here be dragons! Similarly, explaining this takes longer than writing the example itself! Older Windows users will know about .ini files, and Linux Admins are familiar with .conf files. Many of us are already using JSON or YAML formats. Any of these (and more) could be pressed into service, as above. At the 'top end', there are also whole libraries devoted to establishing application configuration or "environments": default values, config files, command-line options, user-input... Have switched to using Python-poetry, which replaces packaging methods such as setuptools (as well as virtual-environment tools). It takes its project configuration specifications from a pyproject.toml file. So, for a few projects lately, I've been using .toml for application-config as well. However, I have to say, this more from an attempt at consistency than a decision of logic. (critique welcome) That said, a setup.py configuration, took the form: setup( name='demo_project', version='1.1.0', packages=find_packages(), install_requires=[ 'requests', 'numpy', ... ], entry_points={ ... Accordingly, it offers an example of the simplest format (for us), and one which has a zero-learning pre-requisite. At execution-time, the moment such a config is import-ed, a syntax-error will immediately bring proceedings to a halt! I have some stats-wonks as clients. They dabble in programming, but (fortunately) realise their limitations. (usually!) The boss has had to ban them from 'improving' my code ($paid to be an improvement on their usual quality), but including a .py configuration/options file has proven to be an honor-preserving compromise. Of course, they manage their own runs, adjusting parameters as they go. So, any errors are their own, and they can fix themselves (without anyone else knowing!). Such would not work in many?most other environments - children: do not try this at home! An irritation for those of us who have to delve into projects after they've been written, is a git-history full of the sorts of user-tweaking changes vilified earlier. Putting user-config into a separate file, even a separate sub-directory, makes it easy to spot which updates to ignore, and thus, which to consider! PS the reason why CrowdStrike was not the end of humanity as we know it, (and only that of those who only know MSFT's eco-system) is because the majority of the world's Internet servers run Linux - including Azure (brings to mind the old saw: the package said "runs on Windows-95 or better" so I installed it on Linux!) Joking aside, we (virtuous ones) ALWAYS test BEFORE release. Correct? -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way? [combining f-string, thousands separator, right align]
On 2024-08-26 at 20:42:32 +1200, dn via Python-list wrote: > and if we really want to go over-board: > > >>> RIGHT_JUSTIFIED = ">" > >>> THOUSANDS_SEPARATOR = "," > >>> s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}" > > or (better) because right-justification is the default for numbers: > > >>> s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}" > > > To the extreme that if your user keeps fiddling with presentations (none > ever do, do they?), all settings to do with s_format could be added to a > config/environment file, and thus be even further separated from > program-logic! And then you'll need a parser, many of whose Unique Challenges™ aren't even apparent until you start parsing files from actual users, and you'll still need some sort of fallback in the code anyway for the case that s_format can't be parsed (for whatever reason). Isn't a config file what just caused the global CrowdStrike outage? ;-) That said, I understand that report generators are a thing, not to mention RPG (https://en.wikipedia.org/wiki/IBM_RPG). Okay, sorry; I'll just crawl back into the hole from whence I came. -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way? [combining f-string, thousands separator, right align]
On 26/08/24 03:12, Gilmeh Serda via Python-list wrote: Subject explains it, or ask. This is a bloody mess: s = "123456789" # arrives as str f"{f'{int(s):,}': >20}" ' 123,456,789' With recent improvements to the expressions within F-strings, we can separate the string from the format required. (reminiscent of FORTRAN which had both WRITE and FORMAT statements, or for that matter HTML which states the 'what' and CSS the 'how') Given that the int() instance-creation has a higher likelihood of data-error, it is recommended that it be a separate operation for ease of fault-finding - indeed some will want to wrap it with try...except. >>> s = "123456789" # arrives as str >>> s_int = int( s ) # makes the transformation obvious and distinct >>> s_format = ">20," # define how the value should be presented >>> F"{s_int:{s_format}}" ' 123,456,789' Further, some of us don't like 'magic-constants', hence (previously): >>> S_FIELD_WIDTH = 20 >>> s_format = F">{S_FIELD_WIDTH}," and if we really want to go over-board: >>> RIGHT_JUSTIFIED = ">" >>> THOUSANDS_SEPARATOR = "," >>> s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}" or (better) because right-justification is the default for numbers: >>> s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}" To the extreme that if your user keeps fiddling with presentations (none ever do, do they?), all settings to do with s_format could be added to a config/environment file, and thus be even further separated from program-logic! -- Regards, =dn -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way? [combining f-string, thousands separator, right align]
On Sun, 25 Aug 2024 15:12:20 GMT Gilmeh Serda via Python-list wrote: >Subject explains it, or ask. > >This is a bloody mess: > s = "123456789" # arrives as str f"{f'{int(s):,}': >20}" >' 123,456,789' > f"{s:>20}" -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way? [combining f-string, thousands separator, right align]
On 2024-08-25 16:12, Gilmeh Serda via Python-list wrote: Subject explains it, or ask. This is a bloody mess: s = "123456789" # arrives as str f"{f'{int(s):,}': >20}" ' 123,456,789' You don't need to format twice; you can combine them: >>> s = "123456789" >>> f'{int(s): >20,}' ' 123,456,789' or if you rely on default behaviour: >>> f'{int(s):20,}' ' 123,456,789' -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way? [combining f-string, thousands separator, right align]
On Sun, 25 Aug 2024 15:12:20 GMT Gilmeh Serda via Python-list wrote: >Subject explains it, or ask. > >This is a bloody mess: > s = "123456789" # arrives as str f"{f'{int(s):,}': >20}" >' 123,456,789' > Oops.. forgot comma f"{int(s):>20,}" -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to create a list of None objects?
On Thu, 12 Aug 2021 09:57:33 +0100, Stephen Tucker declaimed the following: > ># Logic Effect > ># > ># [None * 8]TypeError: unsupported operand type(s) for *: ... > ># [(None) * 8] TypeError: unsupported operand type(s) for *: ... > ># [((None)) * 8]TypeError: unsupported operand type(s) for *: ... > ># [(None,) * 8] [(None, None, None, None, None, None, None, None)] > ># list ((None) * 8) TypeError: unsupported operand type(s) for *: ... > In all the above, you've put the *8 INSIDE the list structure. You "working" example is actually creating a TUPLE stored (as the only element) inside a LIST. >>> [None] * 8 [None, None, None, None, None, None, None, None] >>> Creates a LIST of 8 elements, each being None. -- Wulfraed Dennis Lee Bieber AF6VN wlfr...@ix.netcom.comhttp://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to create a list of None objects?
Thanks for this feedback, Chris, Matthieu. Both are spot on - and thanks for the timing comparison, Matthieu. I suppose I didn't think to try the solution you suggest because I didn't think that I would end up with a single list, but 8 of them. OK, I'll stop wriggling. Stephen. On Thu, Aug 12, 2021 at 10:22 AM Matthieu Dartiailh wrote: > You can achieve the same result by writing: > [None] * 8 > > Comparing both cases in IPython I get: > > In [1]: %timeit list((None,)*8) > 110 ns ± 0.785 ns per loop (mean ± std. dev. of 7 runs, 1000 loops > each) > > In [2]: %timeit [None] * 8 > 88.2 ns ± 0.432 ns per loop (mean ± std. dev. of 7 runs, 1000 loops > each) > > So the list multiplication appears a bit faster. > > Best > > Matthieu > > Le 8/12/2021 à 10:57 AM, Stephen Tucker a écrit : > > Hi, > > > > I thought I'd share the following piece of code that I have recently > written > > (a) to check that what I have done is reasonable - even optimum, > > (b) to inform others who might be wanting to do similar things, and > > (c) to invite comment from the community. > > > > --- > > > > # > > > > # Yes: Create an empty list of Band Limits for this language > > > > # > > > > # Note. The rather complicated logic on the right-hand side of the > > > > # assignment below is used here because none of the following > > > > # alternatives had the desired effect: > > > > # > > > > # Logic Effect > > > > # > > > > # [None * 8]TypeError: unsupported operand type(s) for *: ... > > > > # [(None) * 8] TypeError: unsupported operand type(s) for *: ... > > > > # [((None)) * 8]TypeError: unsupported operand type(s) for *: ... > > > > # [(None,) * 8] [(None, None, None, None, None, None, None, None)] > > > > # list ((None) * 8) TypeError: unsupported operand type(s) for *: ... > > > > # > > > > diclll_BLim [thisISO_] = list ((None,) * 8) > > > > > > --- > > > > Thanks in anticipation. > > > > Stephen Tucker. > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to create a list of None objects?
You can achieve the same result by writing: [None] * 8 Comparing both cases in IPython I get: In [1]: %timeit list((None,)*8) 110 ns ± 0.785 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) In [2]: %timeit [None] * 8 88.2 ns ± 0.432 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each) So the list multiplication appears a bit faster. Best Matthieu Le 8/12/2021 à 10:57 AM, Stephen Tucker a écrit : Hi, I thought I'd share the following piece of code that I have recently written (a) to check that what I have done is reasonable - even optimum, (b) to inform others who might be wanting to do similar things, and (c) to invite comment from the community. --- # # Yes: Create an empty list of Band Limits for this language # # Note. The rather complicated logic on the right-hand side of the # assignment below is used here because none of the following # alternatives had the desired effect: # # Logic Effect # # [None * 8]TypeError: unsupported operand type(s) for *: ... # [(None) * 8] TypeError: unsupported operand type(s) for *: ... # [((None)) * 8]TypeError: unsupported operand type(s) for *: ... # [(None,) * 8] [(None, None, None, None, None, None, None, None)] # list ((None) * 8) TypeError: unsupported operand type(s) for *: ... # diclll_BLim [thisISO_] = list ((None,) * 8) --- Thanks in anticipation. Stephen Tucker. -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to create a list of None objects?
On Thu, Aug 12, 2021 at 6:59 PM Stephen Tucker wrote: > > Hi, > > I thought I'd share the following piece of code that I have recently written > (a) to check that what I have done is reasonable - even optimum, > (b) to inform others who might be wanting to do similar things, and > (c) to invite comment from the community. > > --- > > # > > # Yes: Create an empty list of Band Limits for this language > > # > > # Note. The rather complicated logic on the right-hand side of the > > # assignment below is used here because none of the following > > # alternatives had the desired effect: > > # > > # Logic Effect > > # > > # [None * 8]TypeError: unsupported operand type(s) for *: ... > > # [(None) * 8] TypeError: unsupported operand type(s) for *: ... > > # [((None)) * 8]TypeError: unsupported operand type(s) for *: ... > > # [(None,) * 8] [(None, None, None, None, None, None, None, None)] > > # list ((None) * 8) TypeError: unsupported operand type(s) for *: ... > > # > > diclll_BLim [thisISO_] = list ((None,) * 8) > Why not just: [None] * 8 ? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this snippet?
On Apr 3, 12:26 pm, Alain Ketterlin wrote: > nn writes: > >> > for item in tag23gr: > >> > ... value, key = tuple(item) > >> > ... if(g23tag.get(key)): > >> > ... g23tag[key].append(value) > >> > ... else: > >> > ... g23tag[key] = [value] > > >> for item in tag23gr: > >> g23tag.setdefault(item[0],[]).append(item[1]) > > Or alternatively: > > > from collections import defaultdict > > g23tag = defaultdict(list) > > for item in tag23gr: > > g23tag[item[0]].append(item[1]) > > Very handy in that case, but in general I dislike the idea of silently > inserting a default value when the access is a read, e.g., in > x=g23tag[wrung]. Explicit is better than implicit, as they say. YMMV. > > -- Alain. Valid point. Preferred choice depends on the access patterns to the dict (e.g. one write and multiple reads, multiple writes and one loop over items, etc.) -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this snippet?
nn writes: >> > for item in tag23gr: >> > ... value, key = tuple(item) >> > ... if(g23tag.get(key)): >> > ... g23tag[key].append(value) >> > ... else: >> > ... g23tag[key] = [value] >> >> for item in tag23gr: >> g23tag.setdefault(item[0],[]).append(item[1]) > Or alternatively: > > from collections import defaultdict > g23tag = defaultdict(list) > for item in tag23gr: > g23tag[item[0]].append(item[1]) Very handy in that case, but in general I dislike the idea of silently inserting a default value when the access is a read, e.g., in x=g23tag[wrung]. Explicit is better than implicit, as they say. YMMV. -- Alain. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this snippet?
On Apr 3, 11:02 am, Alain Ketterlin wrote: > python writes: > > tag23gr is a list of lists each with two items. > > g23tag is an empty dictionary when I run the for loop below. > > When is is complete each key is a graphic name who's values are a list > > of tags. > > > for item in tag23gr: > > ... value, key = tuple(item) > > ... if(g23tag.get(key)): > > ... g23tag[key].append(value) > > ... else: > > ... g23tag[key] = [value] > > for item in tag23gr: > g23tag.setdefault(item[0],[]).append(item[1]) > > -- Alain. Or alternatively: from collections import defaultdict g23tag = defaultdict(list) for item in tag23gr: g23tag[item[0]].append(item[1]) -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this snippet?
python wrote: > I played around with a few things and this works but was wondering if > there was a better way to do this. > My first thought was list comprehension but could not get a figure out > the syntax. > > tag23gr is a list of lists each with two items. > g23tag is an empty dictionary when I run the for loop below. > When is is complete each key is a graphic name who's values are a list > of tags. > > for item in tag23gr: > ... value, key = tuple(item) > ... if(g23tag.get(key)): That should be if key in g23tag: Your version means trouble for keys that evaluate to False in a boolean context, e. g. 0, False, None, "", (),... > ... g23tag[key].append(value) > ... else: > ... g23tag[key] = [value] from collections import defaultdict g23tag = defaultdict(list) for value, key in tag23gr: g23tag[key].append(value) -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this snippet?
On Wed, Apr 4, 2012 at 12:36 AM, python wrote: > for item in tag23gr: > ... value, key = tuple(item) > ... if(g23tag.get(key)): > ... g23tag[key].append(value) > ... else: > ... g23tag[key] = [value] Simple enhancement: Use setdefault. Instead of the if, just use: g23tag.setdefault(key,[]).append(value) That'll cover both cases in one. You can leave off the explicit tuple construction; if item is a two-element list, you can unpack it directly. You can also embed that straight into your for loop: for value,key in tag23gr: Do both and you cut your loop down to two lines. Cool! :) Chris Angelico -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this snippet?
python writes: > tag23gr is a list of lists each with two items. > g23tag is an empty dictionary when I run the for loop below. > When is is complete each key is a graphic name who's values are a list > of tags. > > for item in tag23gr: > ... value, key = tuple(item) > ... if(g23tag.get(key)): > ... g23tag[key].append(value) > ... else: > ... g23tag[key] = [value] for item in tag23gr: g23tag.setdefault(item[0],[]).append(item[1]) -- Alain. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to solve this?
On Mon, 23 May 2011 11:55:08 -0700, kracekumar ramaraju wrote: > You can use sizeof function, Who are you talking to, and what question did they ask? Please always quote enough of the post that you are replying to to establish context. a=12234 b=23456.8 a.__sizeof__() > 12 b.__sizeof__() > 16 > So sizeof int is 12 bytes and float is 16 bytes You shouldn't be calling special methods directly (except under unusual circumstances). That's like calling s.__len__() instead of len(s). The public function for getting the size of an object is in the sys module: sys.getsizeof(a) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to solve this?
On 5/23/2011 2:55 PM, kracekumar ramaraju wrote: You can use sizeof function, Appears not to be in manuals, that I could find. As a special method, it is intended to be called through sys.getsizeof. a=12234 b=23456.8 a.__sizeof__() 12 b.__sizeof__() 16 So sizeof int is 12 bytes and float is 16 bytes Depends on system. On my winxp machine, ints are 14 bytes. >>> import sys >>> size = sys.getsizeof >>> size(1) 14 >>> size(1.0) 16 >>> size([]) 36 >>> size([1,2,3]) 48 -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to solve this?
On Mon, May 23, 2011 at 2:55 PM, kracekumar ramaraju wrote: > You can use sizeof function, a=12234 b=23456.8 a.__sizeof__() > 12 b.__sizeof__() > 16 > So sizeof int is 12 bytes and float is 16 bytes I'm not sure what you're trying to show here, but try the following in Python 3.2 >>> a = >>> for i in range(5): ... a*= 10 ... a.__sizeof__() ... -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to solve this?
You can use sizeof function, >>> a=12234 >>> b=23456.8 >>> a.__sizeof__() 12 >>> b.__sizeof__() 16 So sizeof int is 12 bytes and float is 16 bytes -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to solve this?
On Sat, May 21, 2011 at 11:28 PM, Ganapathy Subramanium wrote: > Hello, > > I'm a new bie to python programming and on the processing of learning python > programming. I have coded my first program of fibonnaci generation and would > like to know if there are better ways of achieving the same. > > I still feel quite a few things to be improved. Just wanted experts thoughts > on this. > > try: > > length = input('Enter the length till which you want to generate the > fibonnaci series: \n') > print type(length) > > except: > print 'Invalid input detected' > exit(0) Never use the input() function in Python 2.x; it does an eval(), which is evil. Always use raw_input() and an explicit conversion instead; e.g. Q = 'Enter the length till which you want to generate the fibonnaci series: \n' try: length = int(raw_input(Q)) except ValueError: print 'Invalid input detected' exit(0) Also, as a sidenote: > if type(length) is int: Is normally written: if isinstance(length, int): Cheers, Chris -- http://rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to set a system clock in Python (on a Linux system)
In message , J wrote: > Like I said, it works well, I just wonder if there is a cleaner way of > setting the local clock to a different time in python without having > to do all this. How about one line in Bash: date -s $(date --rfc-3339=date -d "+1 hour") -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to set a system clock in Python (on a Linux system)
man 2 clock_settime call it with ctypes -- Best Regards, -- KDr2 http://kdr2.net On Thu, May 6, 2010 at 10:47 AM, J wrote: > Is there a better way to do this? > > def SkewTime(): >''' >Optional function. We can skew time by 1 hour if we'd like to see real > sync >changes being enforced >''' >TIME_SKEW=1 >logging.info('Time Skewing has been selected. Setting clock ahead 1 > hour') ># Let's get our current time >t = TimeCheck() >logging.info('Current time is: %s' % time.asctime(t)) ># Now create new time string in the form MMDDhhmm for the date > program >hr = t.tm_hour + TIME_SKEW >date_string = time.strftime('%m%d%H%M%Y',(t.tm_year, >t.tm_mon, >t.tm_mday, >hr, >t.tm_min, >t.tm_sec, >t.tm_wday, >t.tm_yday, >t.tm_isdst)) >logging.debug('New date string is: %s' % date_string) >logging.debug('Setting new system time/date') >status = SilentCall('/bin/date %s' % date_string) >logging.info('Pre-sync time is: %s' % time.asctime()) > > TimeCheck() as referenced above is a simple function that just returns > the time.time_struct object from time.localtime(). I pull time a few > times and it was a little cleaner to put that into a function and just > call the function whenever I needed to. > > SilentCall() is a modification of subprocess.call() (which in reality > just calls Popen(*popenargs,**kwargs).wait()) but it defaults to > redirecting stdin and stdout to /dev/null to suppress shell output > from the command being called. > > Anyway, what I'm wondering, is, while this works, is there a better > way to do it than using part of the originally returned time_struct > and injecting my own new hour argument (hr). > > The goal of this function is to just set the system clock one hour > ahead, so when I call the Linux command 'ntpdate' I can get a real > time change when it syncs the local clock to an NTP server. > > This just looks... well, big to me. I tried passing only the things I > really needed to time.strftime(), but apparently, that requires the > full 9-tuple from time_struct, not just individual parts of it. > > Like I said, it works well, I just wonder if there is a cleaner way of > setting the local clock to a different time in python without having > to do all this. The reason most of that exists, is because the linux > date command expects to see the new date/time like this: > MMDDhhmm.ss. > > Or am I just looking at this too hard and really did work it out nicely? > > Cheers > Jeff > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to set a system clock in Python (on a Linux system)
On Wed, May 5, 2010 at 7:47 PM, J wrote: > Is there a better way to do this? Yes: from datetime import datetime, timedelta > def SkewTime(): > ''' > Optional function. We can skew time by 1 hour if we'd like to see real sync > changes being enforced > ''' > TIME_SKEW=1 > logging.info('Time Skewing has been selected. Setting clock ahead 1 hour') > # Let's get our current time skewed = datetime.now() + timedelta(hours=TIME_SKEW) > # Now create new time string in the form MMDDhhmm for the date program date_time_str = skewed.strftime('%m%d%H%M%Y') logging.debug('New date string is: %s' % date_time_str) > logging.debug('Setting new system time/date') status = SilentCall('/bin/date %s' % date_time_str) > logging.info('Pre-sync time is: %s' % time.asctime()) > > Anyway, what I'm wondering, is, while this works, is there a better > way to do it than using part of the originally returned time_struct > and injecting my own new hour argument (hr). Use the datetime module roughly as shown. (Disclaimer: Code is untested). Also, I'm not sure if your original code worked properly after 11PM; my code definitely should. > This just looks... well, big to me. I tried passing only the things I > really needed to time.strftime(), but apparently, that requires the > full 9-tuple from time_struct, not just individual parts of it. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to do this?
"Matt Mitchell" wrote in message news:mailman.65.1267464765.23598.python-l...@python.org... > My initial idea was to make a list of all the different > ways "project" has been capitalized in my repo and try each one. The > code looks like this: I would use pysvn.Client.list to get a list of files at whatever directory level you require. Then you can do a case insensitive compare or whatever else. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
On Thursday, 8 October 2009 18:41:31 Dr. Phillip M. Feldman wrote: > I currently have a function that uses a list internally but then returns > the list items as separate return > values as follows: > > if len(result)==1: return result[0] > if len(result)==2: return result[0], result[1] > > (and so on). Is there a cleaner way to accomplish the same thing? Why do you not change the list into a tuple and return the tuple, and let automatic unpacking handle it? As I see it, the problem is not in the return, but in the call - how do you know now, which of the following to write: answer = thing(params) answer0,answer1 = thing(params) answer0,answer1,answer2 = thing(params) answer0,answer1,answer2,answer3 = thing(params) and so on... probably best to write: answers = thing(params) for answer in answers: do something with answer - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
On Thu, Oct 8, 2009 at 7:14 PM, Dr. Phillip M. Feldman wrote: > > I'm amazed that this works. I had not realized that > > x,y= [3,4] > > is equivalent to > > x= 3; y= 4 > > Python is rather clever. > > Thanks! > Python is very clever: >>> (a, b), c = (1, 2), 3 >>> a, b, c (1, 2, 3) :D -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Dr. Phillip M. Feldman writes: I currently have a function that uses a list internally but then returns the list items as separate return values as follows: if len(result)==1: return result[0] if len(result)==2: return result[0], result[1] (and so on). Is there a cleaner way to accomplish the same thing? The suggestions to return result or if needed tuple(result) are good, if a sequence is expected. But perhaps better if each element has separate meaning: return a defaultdict; document the keys. http://docs.python.org/library/collections.html#collections.defaultdict Cheers, Alan Isaac -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Dr. Phillip M. Feldman wrote: I'm amazed that this works. I had not realized that x,y= [3,4] is equivalent to x= 3; y= 4 Python is rather clever. Thanks! To elaborate on Paul's answer, returning the list will also unpack it if you have it set up that way. E.g. def func(alist): return alist some_list = [1, 2] this, that = func(alist) At least, in 2.5.4 this works. :-) In just about all Python versions for all sequence types, in fact. Mind you, if you don't have the correct number of return names to match the unpacking you'll get the normal errors from that. Yes. This is why people are suggesting that you be consistent about what you return. This is quite different from Matlab where the interpreter knows how many return values the caller is expecting in order to overload functions, but I think it makes for much more understandable code. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
This is an interesting alternative. If one wants to generate everything and return it at one shot, the list approach is better, but there are situations where generating things incrementally is preferrable, e.g., because the caller doesn't know a priori how many things he wants. I will try this out. Thanks! Jack Norton wrote: Dr. Phillip M. Feldman wrote: I currently have a function that uses a list internally but then returns the list items as separate return values as follows: if len(result)==1: return result[0] if len(result)==2: return result[0], result[1] (and so on). Is there a cleaner way to accomplish the same thing? How about using yield and then iterate over the answer: def some_fun(): \tfor result in some_loopable_stuff: \t\t yield result Then call it thusly: for i in some_fun() result = i -Jack (PS, sorry to the OP, you will get two of these -- I forgot to CC the list) -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
I'm amazed that this works. I had not realized that x,y= [3,4] is equivalent to x= 3; y= 4 Python is rather clever. Thanks! To elaborate on Paul's answer, returning the list will also unpack it if you have it set up that way. E.g. def func(alist): return alist some_list = [1, 2] this, that = func(alist) At least, in 2.5.4 this works. :-) Mind you, if you don't have the correct number of return names to match the unpacking you'll get the normal errors from that. Hope this helps! ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list -- View this message in context: http://www.nabble.com/Is-there-a-better-way-to-code-variable-number-of-return-arguments--tp25803294p25813206.html Sent from the Python - python-list mailing list archive at Nabble.com. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Dr. Phillip M. Feldman wrote: I currently have a function that uses a list internally but then returns the list items as separate return values as follows: if len(result)==1: return result[0] if len(result)==2: return result[0], result[1] (and so on). Is there a cleaner way to accomplish the same thing? How about using yield and then iterate over the answer: def some_fun(): \tfor result in some_loopable_stuff: \t\t yield result Then call it thusly: for i in some_fun() result = i -Jack (PS, sorry to the OP, you will get two of these -- I forgot to CC the list) -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Paul Rubin wrote: Ethan Furman writes: some_list = [1, 2] this, that = func(alist) At least, in 2.5.4 this works. :-) But that fails if there are fewer than two elements in the list. It's better to just make the logic either expect a list, or if it's implementing something like an optional value, code it up explicitly. You may even want to return two lists, the second one possibly empty. It also fails if there are more than two elements in the list, as the rest of my post went on to say. I myself would generally not use such a structure, but that doesn't mean the OP doesn't have a good use case for it. Don't forget, his original question indicated that there could be more than two return elements also. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Ethan Furman writes: > some_list = [1, 2] > this, that = func(alist) > > At least, in 2.5.4 this works. :-) But that fails if there are fewer than two elements in the list. It's better to just make the logic either expect a list, or if it's implementing something like an optional value, code it up explicitly. You may even want to return two lists, the second one possibly empty. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Dr. Phillip M. Feldman wrote: I currently have a function that uses a list internally but then returns the list items as separate return values as follows: if len(result)==1: return result[0] if len(result)==2: return result[0], result[1] (and so on). Is there a cleaner way to accomplish the same thing? To elaborate on Paul's answer, returning the list will also unpack it if you have it set up that way. E.g. def func(alist): return alist some_list = [1, 2] this, that = func(alist) At least, in 2.5.4 this works. :-) Mind you, if you don't have the correct number of return names to match the unpacking you'll get the normal errors from that. Hope this helps! ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
On Thu, Oct 8, 2009 at 12:41 PM, Dr. Phillip M. Feldman wrote: > > I currently have a function that uses a list internally but then returns the > list items as separate return > values as follows: > > if len(result)==1: return result[0] > if len(result)==2: return result[0], result[1] > > (and so on). Is there a cleaner way to accomplish the same thing? It kind of depends on how the caller of your function handles the return values. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Dr. Phillip M. Feldman wrote: I currently have a function that uses a list internally but then returns the list items as separate return values as follows: if len(result)==1: return result[0] if len(result)==2: return result[0], result[1] (and so on). Is there a cleaner way to accomplish the same thing? return tuple(result) But you down want to do that, cause the caller will have a hell of a job getting your result. You may want to simply return the list itself. JM -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
Dr. Phillip M. Feldman schrieb: > I currently have a function that uses a list internally but then returns the > list items as separate return > values as follows: > > if len(result)==1: return result[0] > if len(result)==2: return result[0], result[1] > > (and so on). Is there a cleaner way to accomplish the same thing? You can simply "return result". If you want to make sure that you return a copy of the internal list, do "return list(result)" or "return tuple(result)". Christian -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to code variable number of return arguments?
"Dr. Phillip M. Feldman" writes: > if len(result)==1: return result[0] > if len(result)==2: return result[0], result[1] > > (and so on). Is there a cleaner way to accomplish the same thing? That is poor style. Just return the result as a list. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On Wed, 20 May 2009 17:08:08 +0100, walterbyrd wrote: I am processing a huge spreadsheet which I have converted to a csv format. Each row will be a wiki page with several sub-headings. The spreadsheet contains information about servers. Wiki sub-headings may include: 'hardware', 'software', 'users', 'network swith settings'. 'Hardware' may include the spreadsheet columns: 'memory', 'cpu', and so on. So the first six columns in the spreadsheet may go under 'hardware' the next six under 'software' and so on. I have already created the wiki pages, using a method similar to what I first posted. But, it seems like there should be a better way to to do it. So, for future reference, I was just wondering. Given that you're already making presumptions about the nature of your data, named constants or enums are the most concise thing to use together with a quick check of the column header row to make sure that the constants really do refer to the right columns. If you want something a little more bullet-proof, create a dictionary mapping the column headers (as read in) to column numbers and use that to generate the slice limits. Since that still relies on the column headers being what you expect them to be, and at least partially in the order you expect them to be, it's probably not enough of a win to bother with. Trying to slice a list by value is never going to look pretty because lists aren't designed to be indexed by value. Worse, if you were doing this a lot (as you imply) then it's going to be horribly inefficient, since you're doing an extra two (or more) O(n) searches for every row. -- Rhodri James *-* Wildebeeste Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On May 19, 5:31 pm, Ben Finney wrote: > That's just the same micro-goal re-stated. What is your larger problem > of which this is a part? Perhaps a better approach can be suggested when > that context is known. I am processing a huge spreadsheet which I have converted to a csv format. Each row will be a wiki page with several sub-headings. The spreadsheet contains information about servers. Wiki sub-headings may include: 'hardware', 'software', 'users', 'network swith settings'. 'Hardware' may include the spreadsheet columns: 'memory', 'cpu', and so on. So the first six columns in the spreadsheet may go under 'hardware' the next six under 'software' and so on. I have already created the wiki pages, using a method similar to what I first posted. But, it seems like there should be a better way to to do it. So, for future reference, I was just wondering. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
> walterbyrd (w) wrote: >w> On May 8, 5:55 pm, John Yeung wrote: >>> On May 8, 3:03 pm,walterbyrd wrote: >>> >>> > This works, but it seems like there should be a better way. >>> >>> > -- >>> > week = ['sun','mon','tue','wed','thu','fri','sat'] >>> > for day in week[week.index('tue'):week.index('fri')]: >>> > print day >>> > --- >>> >>> I think you should provide much more information, primarily why you >>> want to do this. What is the larger goal you are trying to achieve? >w> I am just looking for a less verbose, more elegant, way to print a >w> slice of a list. What is hard to understand about that? I am not sure >w> how enumerated types help. You didn't say that in the OP. But you can extend the list type to accept slices with strings in them. The language spec says they should be ints but apparently this is not enforced. Of course this makes it vulnerable for future misbehaviour. class KeyList(list): def __getitem__(self, indx): if isinstance(indx, slice): start = indx.start stop = indx.stop # add support for step if you want if not isinstance(start, int): start = self.index(start) if not isinstance(stop, int): stop = self.index(stop) return list.__getitem__(self, slice(start,stop)) return list.__getitem__(self, indx) week = KeyList(['sun','mon','tue','wed','thu','fri','sat']) for day in week['tue':'fri']: print day tue wed thu Note that 'fri' is not included according to standard Python conventions about the end of a slice. Change the code if you are not happy with it and you don't mind getting inconsistent semantics. -- Piet van Oostrum URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4] Private email: p...@vanoostrum.org -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On Tue, 19 May 2009 14:38:19 -0700, walterbyrd wrote: > On May 8, 5:55 pm, John Yeung wrote: >> On May 8, 3:03 pm,walterbyrd wrote: >> >> > This works, but it seems like there should be a better way. >> >> > -- >> > week = ['sun','mon','tue','wed','thu','fri','sat'] for day in >> > week[week.index('tue'):week.index('fri')]: >> > print day >> > --- >> >> I think you should provide much more information, primarily why you >> want to do this. What is the larger goal you are trying to achieve? > > I am just looking for a less verbose, more elegant, way to print a slice > of a list. What is hard to understand about that? I am not sure how > enumerated types help. Printing a slice of a list is about as concise and elegant as possible: print alist[slice_obj] or print alist[start:end:step] But that's not what the example in your first post suggests. Your example suggests you have *two* problems: (1) Given a slice, how to print each item in the slice _individually_. The answer to that is for x in aslice: print x Pretty concise and elegant. (2) Given an arbitrary starting and ending _item_ rather than _position_, how to concisely and elegantly generate a slice. There are many answers, depending on _why_ you want to do this. One possible answer is to write a function to do it: def print_slice(alist, start_item, end_item): start_pos = alist.index(start_item) end_pos = alist.index(end_item) for x in alist[start_pos:end_pos]: print x Now print_slice(week, 'tue', 'fri') is pretty concise and elegant. Another answer is: Don't do that, do something else. If you have an enumerated type, then you could (in principle) do this: week = enumerated('mon tue wed thu fri sat sun') for x in week.tue-week.fri: print x depending on the enumerated type itself naturally. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On May 20, 7:38 am, walterbyrd wrote: > On May 8, 5:55 pm, John Yeung wrote: > > > On May 8, 3:03 pm,walterbyrd wrote: > > > > This works, but it seems like there should be a better way. > > > > -- > > > --- > > > I think you should provide much more information, primarily why you > > want to do this. What is the larger goal you are trying to achieve? > > I am just looking for a less verbose, more elegant, way to print a > slice of a list. What is hard to understand about that? Ummm two things, (1) You didn't say that was what you wanted (2) It's a nonsense anyway: Your original statement "choose a slice of alist": answer = alist [lo:hi] Your current statement "print a slice of a list" (one element per line as per your example): can not be done much less verbosely and more elegantly than: for x in alist[lo:hi]: print x Your real problem appears to be the horrid method of deriving lo and hi. You gave ONE example without stating anything more precise than that it was an example of a slice of a list [which was obvious anyway] and didn't specify in what sense of "better" you wanted a better way. So people have to guess what you really want. Guessing that the 'tue' and 'fri' in your one example will always be constants, here are two options: E.g. given week = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'] Option (1): SUN, MON, TUE, WED, THU, FRI, SAT = range(7) for day in week[TUE:FRI]: print day Option (2): for day in week[2:5]: print day HTH, John -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
walterbyrd writes: > On May 8, 5:55 pm, John Yeung wrote: > > On May 8, 3:03 pm,walterbyrd wrote: > > I think you should provide much more information, primarily why you > > want to do this. What is the larger goal you are trying to achieve? > > I am just looking for a less verbose, more elegant, way to print a > slice of a list. That's just the same micro-goal re-stated. What is your larger problem of which this is a part? Perhaps a better approach can be suggested when that context is known. -- \ “What's another word for Thesaurus?” —Steven Wright | `\ | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On Tue, 19 May 2009 22:38:19 +0100, walterbyrd wrote: On May 8, 5:55 pm, John Yeung wrote: On May 8, 3:03 pm,walterbyrd wrote: > This works, but it seems like there should be a better way. > -- > week = ['sun','mon','tue','wed','thu','fri','sat'] > for day in week[week.index('tue'):week.index('fri')]: > print day > --- I think you should provide much more information, primarily why you want to do this. What is the larger goal you are trying to achieve? I am just looking for a less verbose, more elegant, way to print a slice of a list. What is hard to understand about that? I am not sure how enumerated types help. This is verbose and inelegant because of the way you're storing and using the data, hence (I presume) John's question. The more elegant approach is not to try to index a list with strings, but to keep you "day" data in numeric form and use that to slice with, and for that enums will greatly help you keep things clear. However, whether that's worth doing or not depends on the bigger picture, and you haven't told us anything that would help us figure that out. -- Rhodri James *-* Wildebeeste Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
walterbyrd wrote: On May 8, 5:55 pm, John Yeung wrote: On May 8, 3:03 pm,walterbyrd wrote: This works, but it seems like there should be a better way. -- week = ['sun','mon','tue','wed','thu','fri','sat'] for day in week[week.index('tue'):week.index('fri')]: print day --- I think you should provide much more information, primarily why you want to do this. What is the larger goal you are trying to achieve? I am just looking for a less verbose, more elegant, way to print a slice of a list. week[2:5] # ;-) If you want the interpreter to turn non-ints into ints for you, you will have to give it some sort of function or mapping to use. dayint = {day:i for i,day in enumeratr(week)} # works in Py3 at least week[dayint['tue']:dayint['fri']] # or, untested, basing attrodic on memory of posted code class attrodic(): #py3 def __init__(self, dic): self.__dict__.update(dic) di = attrodic(week) week[di.tue:di.fri] Most elegant, and most setup work ;-). Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On May 8, 5:55 pm, John Yeung wrote: > On May 8, 3:03 pm,walterbyrd wrote: > > > This works, but it seems like there should be a better way. > > > -- > > week = ['sun','mon','tue','wed','thu','fri','sat'] > > for day in week[week.index('tue'):week.index('fri')]: > > print day > > --- > > I think you should provide much more information, primarily why you > want to do this. What is the larger goal you are trying to achieve? I am just looking for a less verbose, more elegant, way to print a slice of a list. What is hard to understand about that? I am not sure how enumerated types help. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On May 8, 3:03 pm, walterbyrd wrote: > This works, but it seems like there should be a better way. > > -- > week = ['sun','mon','tue','wed','thu','fri','sat'] > for day in week[week.index('tue'):week.index('fri')]: > print day > --- I think you should provide much more information, primarily why you want to do this. What is the larger goal you are trying to achieve? In the absence of further information, it seems to me that you are trying to create an enumerated type. For various ideas to achieve this simply, depending on your purpose, see http://norvig.com/python-iaq.html If you want a more thorough treatment, maybe try this package: http://pypi.python.org/pypi/enum/ There may be other recipes and packages; you can Google for them using keywords "python enum" or similar. John -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to chose a slice of a list?
On May 8, 3:03 pm, walterbyrd wrote: > This works, but it seems like there should be a better way. > > -- > week = ['sun','mon','tue','wed','thu','fri','sat'] > for day in week[week.index('tue'):week.index('fri')]: > print day > --- Depending on the context this style might help: >>> week = ['sun','mon','tue','wed','thu','fri','sat'] >>> tue_fri = slice(week.index('tue'), week.index('fri')) >>> for day in week[tue_fri]: print day But I don't really see it as an improvement unless you are using those intervals repeatedly. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
On Sun, 2009-03-08 at 15:49 +1100, Steven D'Aprano wrote: > If the environmental costs of recycling something are worse than the > environmental costs of throwing it away and making a new one, then > recycling that object is actually harmful. But I digress. Unless you live in a country that imports most of these goods, in which case by recycling you keep money in the economy rather than buying goods from elsewhere - it's never mentioned, but I'm fairly certain that's one of the main reasons that the UK government loves forcing us to recycle so much. (obviously doesn't change how "environmentally harmful" something is) Tim Wintle -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Gabriel Genellina wrote: > Imagine you're working with someone side by side. You write a note in a > piece of paper, put it into an envelope, and hand it to your co-worker. He > opens the envelope, throws it away, takes the note and files it inside a > folder right at the end. And you do this over and over. What's wrong in > this story? > > Please save our trees! Don't waste so many envelopes Nice story, but the moral "conserve what you use" is not always good advice. Bits are not envelopes -- sometimes it is more environmentally friendly to throw them away and create new ones. Consider: mylist[:] = [x for x in mylist if not condition(x)] versus: for i in xrange(len(mylist)-1, -1, -1): x = mylist[i] if condition(x): del mylist[i] The first "wastefully" creates a new list, and the second tries to recycle bits by deleting the items in place. Unless mylist is so huge that your computer starts thrashing trying to make two copies in memory, the first is not only simpler to write and understand, but almost certainly much, much faster than the second. That's not the case in this specific example, but as a general principle, it's worth remembering that it's often better to be wasteful with temporary objects than to use miserly algorithms invented for machines with 64K of memory. (The same lessons can apply for re-world considerations as well. Recycling doesn't just happen, it requires energy and water and other costs. If the environmental costs of recycling something are worse than the environmental costs of throwing it away and making a new one, then recycling that object is actually harmful. But I digress.) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Lie Ryan wrote: > mattia wrote: >> Yes, sorry, I have to recycle! But how about this: > rw = [[2,4], [4,5,6],[5,5]] > rw += [[1,1]]*2 > rw >> [[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]] >> How can I recicle in this way using append? > > Not .append() but .extend() Whether you use items += [item]*N or items.extend([item]*N) is mostly a matter of style. You can avoid the intermediate list with items.extend(itertools.repeat(item, N)) but I don't think this approach is faster. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
mattia wrote: Il Sat, 07 Mar 2009 00:05:53 -0200, Gabriel Genellina ha scritto: En Fri, 06 Mar 2009 21:31:01 -0200, mattia escribió: Thanks, I've found another solution here: http://www.obitko.com/tutorials/ genetic-algorithms/selection.php so here is my implementation: def get_fap(fitness, population): fap = [] total = 0 for x in population: f = fitness(x) fap += [(f, x)] total += f return sorted(fap, reverse=True), total Imagine you're working with someone side by side. You write a note in a piece of paper, put it into an envelope, and hand it to your co-worker. He opens the envelope, throws it away, takes the note and files it inside a folder right at the end. And you do this over and over. What's wrong in this story? Please save our trees! Don't waste so many envelopes - that's just what this line does: fap += [(f, x)] Environmentally friendly Pythoneers avoid using discardable intermediate envelopes: fap.append((f, x)) Please recycle! Yes, sorry, I have to recycle! But how about this: rw = [[2,4], [4,5,6],[5,5]] rw += [[1,1]]*2 rw [[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]] rw = [[2,4], [4,5,6],[5,5]] rw.append([1,1]*2) rw [[2, 4], [4, 5, 6], [5, 5], [1, 1, 1, 1]] rw = [[2,4], [4,5,6],[5,5]] rw.append([[1,1]]*2) rw [[2, 4], [4, 5, 6], [5, 5], [[1, 1], [1, 1]]] How can I recicle in this way using append? Not .append() but .extend() >>> rw = [[2,4], [4,5,6],[5,5]] >>> rw.extend([[1,1]]*2) >>> rw > [[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]] -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Sat, 07 Mar 2009 00:05:53 -0200, Gabriel Genellina ha scritto: > En Fri, 06 Mar 2009 21:31:01 -0200, mattia escribió: > >> Thanks, I've found another solution here: >> http://www.obitko.com/tutorials/ >> genetic-algorithms/selection.php >> so here is my implementation: >> >> >> def get_fap(fitness, population): >> fap = [] >> total = 0 >> for x in population: >> f = fitness(x) >> fap += [(f, x)] >> total += f >> return sorted(fap, reverse=True), total > > Imagine you're working with someone side by side. You write a note in a > piece of paper, put it into an envelope, and hand it to your co-worker. > He opens the envelope, throws it away, takes the note and files it > inside a folder right at the end. And you do this over and over. What's > wrong in this story? > > Please save our trees! Don't waste so many envelopes - that's just what > this line does: > > fap += [(f, x)] > > Environmentally friendly Pythoneers avoid using discardable intermediate > envelopes: > > fap.append((f, x)) > > Please recycle! Yes, sorry, I have to recycle! But how about this: >>> rw = [[2,4], [4,5,6],[5,5]] >>> rw += [[1,1]]*2 >>> rw [[2, 4], [4, 5, 6], [5, 5], [1, 1], [1, 1]] >>> rw = [[2,4], [4,5,6],[5,5]] >>> rw.append([1,1]*2) >>> rw [[2, 4], [4, 5, 6], [5, 5], [1, 1, 1, 1]] >>> rw = [[2,4], [4,5,6],[5,5]] >>> rw.append([[1,1]]*2) >>> rw [[2, 4], [4, 5, 6], [5, 5], [[1, 1], [1, 1]]] >>> How can I recicle in this way using append? -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
"Gabriel Genellina" writes: > > for x in population: > > f = fitness(x) > > fap += [(f, x)] > > total += f > > return sorted(fap, reverse=True), total > ... > Environmentally friendly Pythoneers avoid using discardable > intermediate envelopes: > > fap.append((f, x)) I'd probably use: fap = list((fitness(x),x) for x in population) total = sum(x for x,y in fap) return sorted(fap, reverse=True), total -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
En Fri, 06 Mar 2009 21:31:01 -0200, mattia escribió: Thanks, I've found another solution here: http://www.obitko.com/tutorials/ genetic-algorithms/selection.php so here is my implementation: def get_fap(fitness, population): fap = [] total = 0 for x in population: f = fitness(x) fap += [(f, x)] total += f return sorted(fap, reverse=True), total Imagine you're working with someone side by side. You write a note in a piece of paper, put it into an envelope, and hand it to your co-worker. He opens the envelope, throws it away, takes the note and files it inside a folder right at the end. And you do this over and over. What's wrong in this story? Please save our trees! Don't waste so many envelopes - that's just what this line does: fap += [(f, x)] Environmentally friendly Pythoneers avoid using discardable intermediate envelopes: fap.append((f, x)) Please recycle! -- Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Fri, 06 Mar 2009 14:13:47 -0800, Scott David Daniels ha scritto: > mattia wrote: >> Here is my last shot, where I get rid of all the old intermediate >> functions: >> >> def selection(fitness, population): >> lp = len(population) >> roulette_wheel = [] >> for x in population: >> roulette_wheel += [x]*fitness(x) >> selected_population = [[]]*lp >> selected_population[:2] = sorted(population, key=fitness, >> reverse=True)[:2] >> selected_population[2:] = [choice(roulette_wheel) for _ in range >> (lp-2)] > Try something like this to choose likely couples: > > import random > import bisect > > def choose_pairs(fitness_population, decider=random): > '''Pick and yield pairs weighted by fitness for crossing. > > We assume weighted_population has fitness already calculated. > decide is a parameter to allow testing. ''' > total = 0 > cumulative = [] > candidates = [] > for fitness, individual in set(fitness_population): > # calculate total weights, extract real candidates if > fitness > 0: > total += fitness > cumulative.append(total) > candidates.append(individual) > assert len(candidates) > 1 > while True: > # pick a candidate by weight > c0 = decider.random() * total > first = bisect.bisect_left(cumulative, c0) if first: > weighting = cumulative[first] - cumulative[first - 1] > else: > weighting = cumulative[0] > # pick another distinct candidate by fitness c1 = choice = > decider.random() * (total - weighting) if choice >= > cumulative[first] - weighting: > choice += weight # adjust to avoid selecting first > second = bisect.bisect_left(cumulative, choice) yield > candidates[first], candidates[second] > > --Scott David Daniels > scott.dani...@acm.org Thanks, I've found another solution here: http://www.obitko.com/tutorials/ genetic-algorithms/selection.php so here is my implementation: def create_chromosome(min, max, length): return [randint(min, max) for i in range(length)] def create_population(nelem, min, max, length): # preconditions: nelem > 1 and nelem is even if not nelem > 1: nelem = 2 if not nelem%2 == 0: print("The population must have an even number of elements. Correcting...") nelem += 1 return [create_chromosome(min, max, length) for i in range(nelem)] def get_fap(fitness, population): fap = [] total = 0 for x in population: f = fitness(x) fap += [(f, x)] total += f return sorted(fap, reverse=True), total def my_rw(): list, tot = get_fap(sum, pop) r = randint(0, tot-1) i = 0 print(r) for f, e in list: i += f print(i) if i > r: return e return [] # never reached if __name__ == "__main__": pop = create_population(5, 0, 1, 10) # selection_mat(sum, pop) #print(rw(sum, pop)) list, tot = get_fap(sum, pop) print(list) print(tot) for i in range(6): print(my_rw()) -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Fri, 06 Mar 2009 18:46:44 -0300, andrew cooke ha scritto: > i have not been following this discussion in detail, so someone may have > already explained this, but it should not be necessary to actually > construct the roulette wheel to select values from it. what you are > doing is selecting from a list where the there are different > probabilities of selecting different entries. i am pretty sure that can > be done more efficiently than by constructing a new list with many more > entries whose aim is to simulate that (which is what the roulette wheel > seems to be in your code, if i have understood correctly). > > more precisely, i think you can adapt the trick used to select a line at > random from a file by scanning the file just once. > > sorry if i have misunderstood, > andrew Well, I believe that using the right distribution I can for sure find a better way for doing the roulette wheel selection. When I'll have enough time I'll pick up my statistics book. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
mattia wrote: Here is my last shot, where I get rid of all the old intermediate functions: def selection(fitness, population): lp = len(population) roulette_wheel = [] for x in population: roulette_wheel += [x]*fitness(x) selected_population = [[]]*lp selected_population[:2] = sorted(population, key=fitness, reverse=True)[:2] selected_population[2:] = [choice(roulette_wheel) for _ in range (lp-2)] Try something like this to choose likely couples: import random import bisect def choose_pairs(fitness_population, decider=random): '''Pick and yield pairs weighted by fitness for crossing. We assume weighted_population has fitness already calculated. decide is a parameter to allow testing. ''' total = 0 cumulative = [] candidates = [] for fitness, individual in set(fitness_population): # calculate total weights, extract real candidates if fitness > 0: total += fitness cumulative.append(total) candidates.append(individual) assert len(candidates) > 1 while True: # pick a candidate by weight c0 = decider.random() * total first = bisect.bisect_left(cumulative, c0) if first: weighting = cumulative[first] - cumulative[first - 1] else: weighting = cumulative[0] # pick another distinct candidate by fitness c1 = choice = decider.random() * (total - weighting) if choice >= cumulative[first] - weighting: choice += weight # adjust to avoid selecting first second = bisect.bisect_left(cumulative, choice) yield candidates[first], candidates[second] --Scott David Daniels scott.dani...@acm.org -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
i have not been following this discussion in detail, so someone may have already explained this, but it should not be necessary to actually construct the roulette wheel to select values from it. what you are doing is selecting from a list where the there are different probabilities of selecting different entries. i am pretty sure that can be done more efficiently than by constructing a new list with many more entries whose aim is to simulate that (which is what the roulette wheel seems to be in your code, if i have understood correctly). more precisely, i think you can adapt the trick used to select a line at random from a file by scanning the file just once. sorry if i have misunderstood, andrew -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Fri, 06 Mar 2009 22:28:00 +0100, Peter Otten ha scritto: > mattia wrote: > >> Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto: >> >>> mattia wrote: >>> Hi, I'm new to python, and as the title says, can I improve this snippet (readability, speed, tricks): def get_fitness_and_population(fitness, population): return [(fitness(x), x) for x in population] def selection(fitness, population): ''' Select the parent chromosomes from a population according to their fitness (the better fitness, the bigger chance to be selected) ''' selected_population = [] fap = get_fitness_and_population(fitness, population) pop_len = len(population) # elitism (it prevents a loss of the best found solution) # take the only 2 best solutions elite_population = sorted(fap) selected_population += [elite_population[pop_len-1][1]] + [elite_population[pop_len-2][1]] # go on with the rest of the elements for i in range(pop_len-2): # do something >>> >>> def selection1(fitness, population, N=2): >>> rest = sorted(population, key=fitness, reverse=True) best = >>> rest[:N] del rest[:N] >>> # work with best and rest >>> >>> >>> def selection2(fitness, population, N=2): >>> decorated = [(-fitness(p), p) for p in population] >>> heapq.heapify(decorated) >>> >>> best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p >>> for f, p in decorated] >>> # work with best and rest >>> >>> Both implementations assume that you are no longer interested in the >>> individuals' fitness once you have partitioned the population in two >>> groups. >>> >>> In theory the second is more efficient for "small" N and "large" >>> populations. >>> >>> Peter >> >> Ok, but the fact is that I save the best individuals of the current >> population, than I'll have to choose the others elements of the new >> population (than will be N-2) in a random way. The common way is using >> a roulette wheel selection (based on the fitness of the individuals, if >> the total fitness is 200, and one individual has a fitness of 10, that >> this individual will have a 0.05 probability to be selected to form the >> new population). So in the selection of the best solution I have to use >> the fitness in order to get the best individual, the last individual >> use the fitness to have a chance to be selected. Obviously the old >> population anf the new population must have the same number of >> individuals. > > You're right, it was a bad idea. > > Peter Here is my last shot, where I get rid of all the old intermediate functions: def selection(fitness, population): lp = len(population) roulette_wheel = [] for x in population: roulette_wheel += [x]*fitness(x) selected_population = [[]]*lp selected_population[:2] = sorted(population, key=fitness, reverse=True)[:2] selected_population[2:] = [choice(roulette_wheel) for _ in range (lp-2)] -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
mattia wrote: > Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto: > >> mattia wrote: >> >>> Hi, I'm new to python, and as the title says, can I improve this >>> snippet (readability, speed, tricks): >>> >>> def get_fitness_and_population(fitness, population): >>> return [(fitness(x), x) for x in population] >>> >>> def selection(fitness, population): >>> ''' >>> Select the parent chromosomes from a population according to their >>> fitness (the better fitness, the bigger chance to be selected) ''' >>> selected_population = [] >>> fap = get_fitness_and_population(fitness, population) pop_len = >>> len(population) >>> # elitism (it prevents a loss of the best found solution) # take >>> the only 2 best solutions >>> elite_population = sorted(fap) >>> selected_population += [elite_population[pop_len-1][1]] + >>> [elite_population[pop_len-2][1]] >>> # go on with the rest of the elements for i in range(pop_len-2): >>> # do something >> >> def selection1(fitness, population, N=2): >> rest = sorted(population, key=fitness, reverse=True) best = rest[:N] >> del rest[:N] >> # work with best and rest >> >> >> def selection2(fitness, population, N=2): >> decorated = [(-fitness(p), p) for p in population] >> heapq.heapify(decorated) >> >> best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p for >> f, p in decorated] >> # work with best and rest >> >> Both implementations assume that you are no longer interested in the >> individuals' fitness once you have partitioned the population in two >> groups. >> >> In theory the second is more efficient for "small" N and "large" >> populations. >> >> Peter > > Ok, but the fact is that I save the best individuals of the current > population, than I'll have to choose the others elements of the new > population (than will be N-2) in a random way. The common way is using a > roulette wheel selection (based on the fitness of the individuals, if the > total fitness is 200, and one individual has a fitness of 10, that this > individual will have a 0.05 probability to be selected to form the new > population). So in the selection of the best solution I have to use the > fitness in order to get the best individual, the last individual use the > fitness to have a chance to be selected. Obviously the old population anf > the new population must have the same number of individuals. You're right, it was a bad idea. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Fri, 06 Mar 2009 14:06:14 +0100, Peter Otten ha scritto: > mattia wrote: > >> Hi, I'm new to python, and as the title says, can I improve this >> snippet (readability, speed, tricks): >> >> def get_fitness_and_population(fitness, population): >> return [(fitness(x), x) for x in population] >> >> def selection(fitness, population): >> ''' >> Select the parent chromosomes from a population according to their >> fitness (the better fitness, the bigger chance to be selected) ''' >> selected_population = [] >> fap = get_fitness_and_population(fitness, population) pop_len = >> len(population) >> # elitism (it prevents a loss of the best found solution) # take >> the only 2 best solutions >> elite_population = sorted(fap) >> selected_population += [elite_population[pop_len-1][1]] + >> [elite_population[pop_len-2][1]] >> # go on with the rest of the elements for i in range(pop_len-2): >> # do something > > def selection1(fitness, population, N=2): > rest = sorted(population, key=fitness, reverse=True) best = rest[:N] > del rest[:N] > # work with best and rest > > > def selection2(fitness, population, N=2): > decorated = [(-fitness(p), p) for p in population] > heapq.heapify(decorated) > > best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p for > f, p in decorated] > # work with best and rest > > Both implementations assume that you are no longer interested in the > individuals' fitness once you have partitioned the population in two > groups. > > In theory the second is more efficient for "small" N and "large" > populations. > > Peter Ok, but the fact is that I save the best individuals of the current population, than I'll have to choose the others elements of the new population (than will be N-2) in a random way. The common way is using a roulette wheel selection (based on the fitness of the individuals, if the total fitness is 200, and one individual has a fitness of 10, that this individual will have a 0.05 probability to be selected to form the new population). So in the selection of the best solution I have to use the fitness in order to get the best individual, the last individual use the fitness to have a chance to be selected. Obviously the old population anf the new population must have the same number of individuals. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Chris Rebert writes: >for i in range(len(fap)): >selected_population.append(choice(rw)) "for i in range(len(something))" is a bit of a code smell. You could instead say: selected_population.extend(choice(rw) for x in fap) The unused "x" is also a slight code smell, but the most obvious cures involve using the itertools module in ways that are worse than the disease. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
mattia wrote: > Hi, I'm new to python, and as the title says, can I improve this snippet > (readability, speed, tricks): > > def get_fitness_and_population(fitness, population): > return [(fitness(x), x) for x in population] > > def selection(fitness, population): > ''' > Select the parent chromosomes from a population according to their > fitness (the better fitness, the bigger chance to be selected) > ''' > selected_population = [] > fap = get_fitness_and_population(fitness, population) > pop_len = len(population) > # elitism (it prevents a loss of the best found solution) > # take the only 2 best solutions > elite_population = sorted(fap) > selected_population += [elite_population[pop_len-1][1]] + > [elite_population[pop_len-2][1]] > # go on with the rest of the elements > for i in range(pop_len-2): > # do something def selection1(fitness, population, N=2): rest = sorted(population, key=fitness, reverse=True) best = rest[:N] del rest[:N] # work with best and rest def selection2(fitness, population, N=2): decorated = [(-fitness(p), p) for p in population] heapq.heapify(decorated) best = [heapq.heappop(decorated)[1] for _ in range(N)] rest = [p for f, p in decorated] # work with best and rest Both implementations assume that you are no longer interested in the individuals' fitness once you have partitioned the population in two groups. In theory the second is more efficient for "small" N and "large" populations. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
On Fri, Mar 6, 2009 at 3:52 AM, mattia wrote: > Il Fri, 06 Mar 2009 03:43:22 -0800, Chris Rebert ha scritto: > >> On Fri, Mar 6, 2009 at 3:07 AM, mattia wrote: >>> Great, the for statement has not to deal with fap anymore, but with >>> another sequence, like this: >>> >>> def get_roulette_wheel(weight_value_pairs): >>> roulette_wheel = [] >>> for weight, value in weight_value_pairs: >>> roulette_wheel += [value]*weight >>> return roulette_wheel >>> >>> def selection(fitness, population): >>> ... >>> rw = get_roulette_wheel(fap) >>> for i in range(pop_len-2): >>> selected_population += [choice(rw)] >>> return selected_population >>> >>> I think that using [choice(rw)]*len(fap) will produce the same sequence >>> repeted len(fap) times... >> >> Revision to this new code: >> >> def get_roulette_wheel(weight_value_pairs): >> return [[value]*weight for weight, value in weight_value_pairs] >> >> def selection(fitness, population): >> ... >> rw = get_roulette_wheel(fap) >> for i in range(len(fap)): >> selected_population.append(choice(rw)) >> return selected_population >> >> Cheers, >> Chris > > Great, append is equivalent to += right? or more efficient? Yes. .append(item) is equivalent to += [item] and is more efficient. Cheers, Chris -- I have a blog: http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Fri, 06 Mar 2009 03:43:22 -0800, Chris Rebert ha scritto: > On Fri, Mar 6, 2009 at 3:07 AM, mattia wrote: >> Great, the for statement has not to deal with fap anymore, but with >> another sequence, like this: >> >> def get_roulette_wheel(weight_value_pairs): >> roulette_wheel = [] >> for weight, value in weight_value_pairs: >> roulette_wheel += [value]*weight >> return roulette_wheel >> >> def selection(fitness, population): >> ... >> rw = get_roulette_wheel(fap) >> for i in range(pop_len-2): >> selected_population += [choice(rw)] >> return selected_population >> >> I think that using [choice(rw)]*len(fap) will produce the same sequence >> repeted len(fap) times... > > Revision to this new code: > > def get_roulette_wheel(weight_value_pairs): >return [[value]*weight for weight, value in weight_value_pairs] > > def selection(fitness, population): >... >rw = get_roulette_wheel(fap) >for i in range(len(fap)): >selected_population.append(choice(rw)) >return selected_population > > Cheers, > Chris Great, append is equivalent to += right? or more efficient? -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
On Fri, Mar 6, 2009 at 3:07 AM, mattia wrote: > Great, the for statement has not to deal with fap anymore, but with > another sequence, like this: > > def get_roulette_wheel(weight_value_pairs): > roulette_wheel = [] > for weight, value in weight_value_pairs: > roulette_wheel += [value]*weight > return roulette_wheel > > def selection(fitness, population): > ... > rw = get_roulette_wheel(fap) > for i in range(pop_len-2): > selected_population += [choice(rw)] > return selected_population > > I think that using [choice(rw)]*len(fap) will produce the same sequence > repeted len(fap) times... Revision to this new code: def get_roulette_wheel(weight_value_pairs): return [[value]*weight for weight, value in weight_value_pairs] def selection(fitness, population): ... rw = get_roulette_wheel(fap) for i in range(len(fap)): selected_population.append(choice(rw)) return selected_population Cheers, Chris -- I have a blog: http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
Il Fri, 06 Mar 2009 10:19:22 +, mattia ha scritto: > Hi, I'm new to python, and as the title says, can I improve this snippet > (readability, speed, tricks): > > def get_fitness_and_population(fitness, population): > return [(fitness(x), x) for x in population] > > def selection(fitness, population): > ''' > Select the parent chromosomes from a population according to their > fitness (the better fitness, the bigger chance to be selected) ''' > selected_population = [] > fap = get_fitness_and_population(fitness, population) pop_len = > len(population) > # elitism (it prevents a loss of the best found solution) # take the > only 2 best solutions > elite_population = sorted(fap) > selected_population += [elite_population[pop_len-1][1]] + > [elite_population[pop_len-2][1]] > # go on with the rest of the elements for i in range(pop_len-2): > # do something Great, the for statement has not to deal with fap anymore, but with another sequence, like this: def get_roulette_wheel(weight_value_pairs): roulette_wheel = [] for weight, value in weight_value_pairs: roulette_wheel += [value]*weight return roulette_wheel def selection(fitness, population): ... rw = get_roulette_wheel(fap) for i in range(pop_len-2): selected_population += [choice(rw)] return selected_population I think that using [choice(rw)]*len(fap) will produce the same sequence repeted len(fap) times... -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of doing this?
On Fri, Mar 6, 2009 at 2:19 AM, mattia wrote: > Hi, I'm new to python, and as the title says, can I improve this snippet > (readability, speed, tricks): > > def get_fitness_and_population(fitness, population): > return [(fitness(x), x) for x in population] > > def selection(fitness, population): > ''' > Select the parent chromosomes from a population according to their > fitness (the better fitness, the bigger chance to be selected) > ''' > selected_population = [] > fap = get_fitness_and_population(fitness, population) > pop_len = len(population) > # elitism (it prevents a loss of the best found solution) > # take the only 2 best solutions > elite_population = sorted(fap) > selected_population += [elite_population[pop_len-1][1]] + > [elite_population[pop_len-2][1]] > # go on with the rest of the elements > for i in range(pop_len-2): > # do something Removing the unnecessary use of sorted() and using list.pop() rather than explicit indices: def selection(fitness, population): ''' Select the parent chromosomes from a population according to their fitness (the better fitness, the bigger chance to be selected) ''' fap = get_fitness_and_population(fitness, population) fap.sort() # elitism (it prevents a loss of the best found solution) # take the only 2 best solutions selected_population = [fap.pop()[1] for i in range(2)] # go on with the rest of the elements for fit, pop in fap: #do something Cheers, Chris -- I have a blog: http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to implement this:
Paul Boddie wrote: > Michael Yanowitz wrote: >> >>I guess I am looking for something portable (both >> Windows and Linux) where I can abort a function after >> a certain time limit expires. > > Doing a search for "timeout function Python" on Google reveals a number > of approaches. > Using threads: > > * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878 That doesn't abort the calculation, however -- it just moves on with a default value instead of the actual result if that is not available after the specified timespan. The calculation may go on forever eating up resources. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to implement this:
Michael Yanowitz wrote: > >I guess I am looking for something portable (both > Windows and Linux) where I can abort a function after > a certain time limit expires. Doing a search for "timeout function Python" on Google reveals a number of approaches. Using signals: * http://nick.vargish.org/clues/python-tricks.html * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307871 Using threads: * http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878 Using processes: * http://lfw.org/python/delegate.html Paul -- http://mail.python.org/mailman/listinfo/python-list
RE: Is there a better way to implement this:
Thanks. I suppose I could have used time.sleep(seconds) here. I did it in 0.01 because in an earlier verion, I did something else between the sleeps. I guess I am looking for something portable (both Windows and Linux) where I can abort a function after a certain time limit expires. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Benjamin Niemann Sent: Monday, January 22, 2007 11:19 AM To: python-list@python.org Subject: Re: Is there a better way to implement this: Michael Yanowitz wrote: > Hello: > >I wrote the code below (much irrelevant code removed). > This doesn't quite work. What I wanted it to do was > a) Execute function ftimed, which takes a function and a timeout > in seconds. > b) This will also execute function abort() as a thread. > This function just runs for the specified > number of seconds and returns. > However, before it returns, throws an exception. > c) If test() is still running when abort() is > finished, ftimed() should catch the exception and > return. > > It is catching the exception, however it continues running the function. > Why does it continue and not return? The exception is raised in the thread that executes the abort() function. The exception does not get caught and terminates this thread. The other (main) thread is unaffected - exceptions are local to a thread and there is currently no (portable) way to raise an exception in another thread. > What am I missing, or is there a better way to > implement this (having ftimed() return when the > abort-timer time is exceeded? You may use the signal.alarm() function, if you are on a UNIXoid system and you have only a signle time-out at a time (e.g. not nested). > import time, thread, sys > > thread_finished = "MAX RUN TIME EXCEEDED!" > > def abort (seconds): > start_time = time.time() > while ((time.time() - start_time) < seconds): > time.sleep(0.01) any reason for not using time.sleep(seconds) here? I suppose I could have, but in earlier versions > print "script run time exceeded max_run_time of", seconds, "seconds." > raise thread_finished > return > > > def test(): > i = 0 > while (True): >time.sleep(1) >print "HELLO", i >i+=1 > > > def ftimed (func, seconds): > thread.start_new_thread (abort, (seconds,)) > > try: > func() > except thread_finished: > print "Timeout" > return > > ftimed (test, 30) > print "Script finished" -- Benjamin Niemann Email: pink at odahoda dot de WWW: http://pink.odahoda.de/ -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way to implement this:
Michael Yanowitz wrote: > Hello: > >I wrote the code below (much irrelevant code removed). > This doesn't quite work. What I wanted it to do was > a) Execute function ftimed, which takes a function and a timeout > in seconds. > b) This will also execute function abort() as a thread. > This function just runs for the specified > number of seconds and returns. > However, before it returns, throws an exception. > c) If test() is still running when abort() is > finished, ftimed() should catch the exception and > return. > > It is catching the exception, however it continues running the function. > Why does it continue and not return? The exception is raised in the thread that executes the abort() function. The exception does not get caught and terminates this thread. The other (main) thread is unaffected - exceptions are local to a thread and there is currently no (portable) way to raise an exception in another thread. > What am I missing, or is there a better way to > implement this (having ftimed() return when the > abort-timer time is exceeded? You may use the signal.alarm() function, if you are on a UNIXoid system and you have only a signle time-out at a time (e.g. not nested). > import time, thread, sys > > thread_finished = "MAX RUN TIME EXCEEDED!" > > def abort (seconds): > start_time = time.time() > while ((time.time() - start_time) < seconds): > time.sleep(0.01) any reason for not using time.sleep(seconds) here? > print "script run time exceeded max_run_time of", seconds, "seconds." > raise thread_finished > return > > > def test(): > i = 0 > while (True): >time.sleep(1) >print "HELLO", i >i+=1 > > > def ftimed (func, seconds): > thread.start_new_thread (abort, (seconds,)) > > try: > func() > except thread_finished: > print "Timeout" > return > > ftimed (test, 30) > print "Script finished" -- Benjamin Niemann Email: pink at odahoda dot de WWW: http://pink.odahoda.de/ -- http://mail.python.org/mailman/listinfo/python-list
Test functions and test discovery (was: Re: Is there a better way of accessing functions in a module?)
"Ant" <[EMAIL PROTECTED]> writes: > def a_test(): > print "Test A" > > def b_test(): > print "Test B" Incidentally, the convention is to name test functions as 'test_foo' not 'foo_test'; this will make your module more easily compatible with existing testing tools. > if __name__ == "__main__": > tests = ["%s()" % x for x in dir() if x.endswith("test")] > > for test in tests: > eval(test) No need for eval. (You already found globals(), so I'll use that.) if __name__ == "__main__": test_funcs = [x for name, x in globals() if name.startswith("test") and hasattr(x, "__call__") ] for test in test_funcs: test() I'll concur with other posters on this thread and encourage you to consider using the standard 'unittest' module, and recommend 'nose' for test discovery and execution: http://somethingaboutorange.com/mrl/projects/nose/> -- \ "Unix is an operating system, OS/2 is half an operating system, | `\ Windows is a shell, and DOS is a boot partition virus." -- | _o__) Peter H. Coffin | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of accessing functions in a module?
Ant wrote: > Ant wrote: > ... >> But this feels like a hack... Is there a cleaner way for accessing the >> functions of the current module similar to the __dict__ attribute of >> classes? i.e. a way to access the local symbol table? > > Sorry - posted too soon. Found the globals() built-in... You can also import __main__ tests = [x for x in dir(__main__) if x.endswith("test")] for test in tests: getattr(__main__, test)() but I second the suggestion of looking in to unittest or one of the other test frameworks. Kent -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of accessing functions in a module?
Yes, you can go that route. But since it appears that what you are doing is unit testing related, and you are interested in aranging for all of your unit test cases to be run automatically, I'd suggest using the unittest module. -- http://mail.python.org/mailman/listinfo/python-list
Re: Is there a better way of accessing functions in a module?
Ant wrote: ... > But this feels like a hack... Is there a cleaner way for accessing the > functions of the current module similar to the __dict__ attribute of > classes? i.e. a way to access the local symbol table? Sorry - posted too soon. Found the globals() built-in... -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[EMAIL PROTECTED] wrote: > Problem: > > You have a list of unknown length, such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. > > I have been using something like this: > _ > > while list[0] != O: > storage.append(list[0]) > list.pop(0) > if len(list) == 0: > break > _ > > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? It seems few suggested solutions actually do the same thing as your code shows. I think this does. (Untested) try: ix = aList.index(O) storage, aList = aList[:ix], aList[ix:] except ValueError: # No O's storage, aList = aList, [] The main advantage with my approach over yours is that all iterations, all the looping, takes place in fast C code, unless your list elements are Python classes that implement __cmp__ etc. If testing 'aList[0] == O' involves Python, things might slow down a bit... .index() takes linear time, but it's fairly fast. As Alex suggested, you might want to replace it with a O(log n) solution for big lists. You might need rather big lists for the Python based O(log n) to get faster than the C based O(n) though. Measure. -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
Bruno Desthuilliers wrote: > [EMAIL PROTECTED] a écrit : > > Problem: > > > > You have a list of unknown length, > > This doesn't exist in Python: >len(alist) > > > such as this: list > [X,X,X,O,O,O,O]. You want to extract all and only the > > X's. > > braindead solution - relying on zeros being zeros or any other False value: > all_xxx > > You know > > the X's are all up front and you know that the item after the last X is > > an O, or that the list ends with an X. There are never O's between > > X's. > > > > Then it *may* be possible to optimize - but code will break as soon as > this rule change. So is there a real need for optimisation ? (hint: dont > guess, profile) > > > FWIW, I've collected all suggestions here (and perhaps some others) and > hacked a Q&D benchmark. Usage is: > > python test_lists.py [repeat [list_size [xcount]] > > where: > * repeat is the number of iteration, default to 1000 > * list_size is the size of the list, default to 100 > * xcount is the number or non-zero values in the list, default is random > > I've run it a few times, and it seems that in most cases, > * the bisect-like approach (Alex Martelli / Karl Friedrich Bolz) is > the winner > * the while/pop approach of the OP (slightly rewritten...) is really wrong > > FWIW, one of the dummiest possible approach IMHO > (ie filter(None, alist)) behaves quite correctly wrt some other > 'optimized' approachs - and is still safe if the rules about the > composition of the list changes... Could it be that no optimization is > sometime the best optimisation ?-) > > > # test_lists.py > from itertools import takewhile > from timeit import Timer > from random import randint > > def get_list(size, xcount=None): > if xcount is None: > xcount else: > assert xcount < zcount return [1] * xcount + [0] * zcount > > def with_while(alist): > res while alist and alist[0]: > res.append(alist.pop(0)) > return res > > def with_for(alist): > res for x in alist: > if not x: break > res.append(x) > return res > > def with_filter(alist): > return filter(None, alist) > > def with_comprehension(alist): > return [x for x in alist if x] > > def with_takewhile(alist): > return list(takewhile(lambda x: x!=0, alist)) > > def with_slice_try(alist): > try: > return alist[:alist.index(0)] > except ValueError: > return alist[:] > > def with_slice_safe(alist): > alist.append(0) > return alist[:alist.index(0)] > > def with_delslice_safe(alist): > alist.append(0) > del alist[alist.index(0):] > return alist > > def with_sect(alist): > low high while low < high: > mid if alist[mid] = 0: > high else: > low return alist[:low] > > _candidates if n.startswith('with_') and callable(o)] > > def run_test(repeat00, list_size='100', xcount='None'): > global _candidate > > print """ > params : > * repeat : %s > * list_size : %s > * xcounts : %s > """ % (repeat, list_size, xcount) > results for n in _candidates: > stm, stp 'from __main__ import %s, get_list' % > n) > results[n] > sorted_resultsfor n, time in > results.items()]) > for _, result in sorted_results: > print "%s : %s" % result > > > def main(args): > try: > repeat except: > repeat try: > list_size except: > list_size try: > xcount except: > xcount > run_test(repeat, list_size, xcount) > > if __name__ = '__main__': > import sys > main(sys.argv[1:]) > > > HTH -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[EMAIL PROTECTED] a écrit : > Problem: > > You have a list of unknown length, This doesn't exist in Python: len(alist) > such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. braindead solution - relying on zeros being zeros or any other False value: all_xxx = filter(None, [X,X,X,O,O,O,O]) > You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. > Then it *may* be possible to optimize - but code will break as soon as this rule change. So is there a real need for optimisation ? (hint: dont guess, profile) FWIW, I've collected all suggestions here (and perhaps some others) and hacked a Q&D benchmark. Usage is: python test_lists.py [repeat [list_size [xcount]] where: * repeat is the number of iteration, default to 1000 * list_size is the size of the list, default to 100 * xcount is the number or non-zero values in the list, default is random I've run it a few times, and it seems that in most cases, * the bisect-like approach (Alex Martelli / Karl Friedrich Bolz) is the winner * the while/pop approach of the OP (slightly rewritten...) is really wrong FWIW, one of the dummiest possible approach IMHO (ie filter(None, alist)) behaves quite correctly wrt some other 'optimized' approachs - and is still safe if the rules about the composition of the list changes... Could it be that no optimization is sometime the best optimisation ?-) # test_lists.py from itertools import takewhile from timeit import Timer from random import randint def get_list(size, xcount=None): if xcount is None: xcount = randint(1, size) else: assert xcount <= size zcount = size - xcount return [1] * xcount + [0] * zcount def with_while(alist): res = [] while alist and alist[0]: res.append(alist.pop(0)) return res def with_for(alist): res = [] for x in alist: if not x: break res.append(x) return res def with_filter(alist): return filter(None, alist) def with_comprehension(alist): return [x for x in alist if x] def with_takewhile(alist): return list(takewhile(lambda x: x!=0, alist)) def with_slice_try(alist): try: return alist[:alist.index(0)] except ValueError: return alist[:] def with_slice_safe(alist): alist.append(0) return alist[:alist.index(0)] def with_delslice_safe(alist): alist.append(0) del alist[alist.index(0):] return alist def with_sect(alist): low = 0 high = len(alist) while low < high: mid = (low + high) // 2 if alist[mid] == 0: high = mid else: low = mid + 1 return alist[:low] _candidates = [n for n, o in locals().copy().items() \ if n.startswith('with_') and callable(o)] def run_test(repeat=1000, list_size='100', xcount='None'): global _candidate print """ params : * repeat : %s * list_size : %s * xcounts : %s """ % (repeat, list_size, xcount) results = {} for n in _candidates: stm, stp = ('%s(get_list(%s, %s))' % (n, list_size, xcount), 'from __main__ import %s, get_list' % n) results[n] = Timer(stm, stp).timeit(repeat) sorted_results = sorted([(time, (n, time)) \ for n, time in results.items()]) for _, result in sorted_results: print "%s : %s" % result def main(args): try: repeat = int(args.pop(0)) except: repeat = 1000 try: list_size = args.pop(0) except: list_size = '100' try: xcount = args.pop(0) except: xcount = 'None' # -> random run_test(repeat, list_size, xcount) if __name__ == '__main__': import sys main(sys.argv[1:]) HTH -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
Charles Krug <[EMAIL PROTECTED]> wrote: > On 2006-02-11, Alex Martelli <[EMAIL PROTECTED]> wrote: > > [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > > > >> Problem: > >> > >> You have a list of unknown length, such as this: list = > >> [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > >> the X's are all up front and you know that the item after the last X is > >> an O, or that the list ends with an X. There are never O's between > >> X's. > > > > If the list is incredibly long, you should use a bisection approach. > > Standard module bisect in the Python library could help, but mostly as > > an _example_, since it unfortunately relies on normal alphabetic order, > > and alphabetically speaking X should come _after_ O, not _before_. > > Isn't every call to list.index() an O(n) operation? We certainly want > to avoid multiple calls there if we can. Why should we have ANY call to index whatsoever? > What happens if your split occurs in the middle of your block of Xs? > Then the split before/after fails --the stated algorithm says, "If the > split is an X, choose the front half," so perhaps the statement was > inprecise? What statement? What are you TALKING about?! What I said, and you don't quote, was: > > 2. if it's an X, so are all previous items -- recurse to second half how can you POSSIBLY read this as "choose the front half"?! I say to recurse (iteration works, too, but it's even trickier to code) to the SECOND half, to find the first-if-any non-'X'. > The only way you'll know if you have an X in a particular block is using > a linear search method, either in Python or with list.index() Reread markscala's problem statement: all the Xs are up front followed by 0 or more Os. So, the list is L = ['X']*N + ['O']*M for unknown N>=0 and M>=0. All we have to do is find N and M (if we know either, the other is immediately computed, since N+M==len(L) and len() is O(1)). > If (as the OP seemed to state) we KNOW that there's only one block of > X's in the list: > > 1. Find the index of the first X Why would we do that? He stated, very clearly, and you and I have both been quoting: > >> You know > >> the X's are all up front So why would we do any work to find out what we altrady know? > 2. Find the index of the last X. Yep, the only certain task, and it's O(log(N+M)). > 3. Delete the block we've found. And the deletion is definitely linear time (and trivial), of course. I was focusing on the only interesting part, (2). > Judging from way the OP worded the question, I'd advise making something > that works and that you understand how it works. > > After that, s/he can worry about whether or not its performance is > suboptimal. And indeed, part of what I said (and again you're snipping it rather than quoting it was: > > If N is not too huge, O(N) might be OK, and is, of course, way simpler > > to code!-) However, even though the O(N) in the deletion subtask would appear to justify this shortcut, I think the task is way too trivial to justify a linear-time approach to point 2 -- the obvious N = L.count('X'), of course. It seems likely that the whole purpose of the exercise (probably homework) is to have the student identify and develop a bisection (a notoriously tricky-to-code thing). Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
Hi! [EMAIL PROTECTED] wrote: > Problem: > > You have a list of unknown length, such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. > > I have been using something like this: > _ > > while list[0] != O: > storage.append(list[0]) > list.pop(0) > if len(list) == 0: > break > _ > > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? Depends on what you mean with "better". I (heavily inspired by the bisect module) came up with: low = 0 high = len(L) while low < high: mid = (low + high) // 2 if L[mid] == 0: high = mid else: low = mid + 1 storage = L[:low] This has the advantage to be more efficient compared to other approaches, which of course only matters if your list is big. It still features a "while" loop, though. > hope this is clear. It is not entirely clear what the X is supposed to be. I assumed that it can be anything except 0. Cheers, Carl Friedrich -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
Alex Martelli wrote: > [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > > >>Problem: >> >>You have a list of unknown length, such as this: list = >>[X,X,X,O,O,O,O]. You want to extract all and only the X's. You know >>the X's are all up front and you know that the item after the last X is >>an O, or that the list ends with an X. There are never O's between >>X's. > > > If the list is incredibly long, you should use a bisection approach. > Standard module bisect in the Python library could help, but mostly as > an _example_, since it unfortunately relies on normal alphabetic order, > and alphabetically speaking X should come _after_ O, not _before_. > > But the algorithm is still sound: > > 1. look at the midpoint. > 2. if it's an X, so are all previous items -- recurse to second half > 3. if it's an O, so are all following items -- recurse to first half > > Getting all conditions exactly right is tricky (which is why bisect is a > good model!), but this way you get O(log N) performance for a list of > length N. > > If N is not too huge, O(N) might be OK, and is, of course, way simpler > to code!-) > The code would look something like this: low = 0 high = len(L) while low < high: mid = (low + high) // 2 if L[mid] == 0: high = mid else: low = mid + 1 list_of_X = L[:low] Cheers, Carl Friedrich Bolz -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[EMAIL PROTECTED] wrote: > Problem: > > You have a list of unknown length, such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. > > I have been using something like this: > _ > > while list[0] != O: > storage.append(list[0]) > list.pop(0) > if len(list) == 0: > break > _ > > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? > > hope this is clear. >>> X = "X" >>> O = "O" >>> def fl(l): ... for i, v in enumerate(l): ... if v == O: ... return l[:i] ... return l ... >>> fl([X,X,X,X,O,O,O]) ['X', 'X', 'X', 'X'] >>> fl([]) [] >>> fl([O]) [] >>> fl([X]) ['X'] >>> regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC www.holdenweb.com PyCon TX 2006 www.python.org/pycon/ -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
On 2006-02-11, Alex Martelli <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > >> Problem: >> >> You have a list of unknown length, such as this: list = >> [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know >> the X's are all up front and you know that the item after the last X is >> an O, or that the list ends with an X. There are never O's between >> X's. > > If the list is incredibly long, you should use a bisection approach. > Standard module bisect in the Python library could help, but mostly as > an _example_, since it unfortunately relies on normal alphabetic order, > and alphabetically speaking X should come _after_ O, not _before_. > Isn't every call to list.index() an O(n) operation? We certainly want to avoid multiple calls there if we can. What happens if your split occurs in the middle of your block of Xs? Then the split before/after fails --the stated algorithm says, "If the split is an X, choose the front half," so perhaps the statement was inprecise? The only way you'll know if you have an X in a particular block is using a linear search method, either in Python or with list.index() If (as the OP seemed to state) we KNOW that there's only one block of X's in the list: 1. Find the index of the first X 2. Find the index of the last X. 3. Delete the block we've found. That relies on the underlying language, which means we're working in "Linear Time in C", more or less. If we make no such guarantee, then I can do the operation in linear "Python Time" by scanning the list once, finding each instance and calling list.del() as I find each block, keeping track of my current position so I don't have to start over again. Judging from way the OP worded the question, I'd advise making something that works and that you understand how it works. After that, s/he can worry about whether or not its performance is suboptimal. How large must the list be before "logarithmic Python algorithm" is faster than "linear C algorithm"? I've never measured, but it may be a question worth exploring if one has a huge pile of data to chew on--like US Census or UN budget-sized. -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
"[EMAIL PROTECTED]" <[EMAIL PROTECTED]> writes: > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? Note that "list" is the name of a built-in type; I used "mylist". Alex Martelli described how to do it in log n time using the bisect module. Here's a dumb linear time method that might be faster for small n (of course you should time the different methods for your particular Python implementation, if the speed matters): del mylist[len(mylist) - mylist.count(0):] The above an example of where the natural del mylist[-mylist.count(0):] does totally the wrong thing if there are no 0's in the list. There was a huge thread a while back about ways to fix that. Another way, might be faster, esp. there's more than a few 0's: try: del mylist[mylist.index(0)] except ValueError: pass # no 0's in the list -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > Problem: > > You have a list of unknown length, such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. If the list is incredibly long, you should use a bisection approach. Standard module bisect in the Python library could help, but mostly as an _example_, since it unfortunately relies on normal alphabetic order, and alphabetically speaking X should come _after_ O, not _before_. But the algorithm is still sound: 1. look at the midpoint. 2. if it's an X, so are all previous items -- recurse to second half 3. if it's an O, so are all following items -- recurse to first half Getting all conditions exactly right is tricky (which is why bisect is a good model!), but this way you get O(log N) performance for a list of length N. If N is not too huge, O(N) might be OK, and is, of course, way simpler to code!-) Alex -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
On Sat, 11 Feb 2006 01:37:59 +0100 in comp.lang.python, Schüle Daniel <[EMAIL PROTECTED]> wrote: >Lonnie Princehouse wrote: >> everybody is making this way more complicated than it needs to be. >> >> storage = list[:list.index(O)] > >the question is whether the old list is needed in the future or not >if not then it would be easer/mor efficient to use > >del lst[lst.index(0):] And you're both forgetting the list can end with X. the index method raises a ValueError exception if the desired value is not found in the list. Assuming you want to keep the original list and create a new list called storage, you could try if lst[-1] == X: storage = lst[:] else: storage = lst[:lst.index(O)] or even try: storage = lst[:lst.index(O)] except ValueError: storage = lst[:] (WARNING: untested!) Regards, -=Dave -- Change is inevitable, progress is not. -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
Scott David Daniels wrote: > [EMAIL PROTECTED] wrote: >> Problem: >> >> You have a list of unknown length, such as this: list = >> [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know >> the X's are all up front and you know that the item after the last X is >> an O, or that the list ends with an X. There are never O's between >> X's. >> >> I have been using something like this: >> while list[0] != O: >> storage.append(list[0]) >> list.pop(0) >> if len(list) == 0: >> break >> But this seems ugly to me, and using "while" give me the heebies. Is >> there a better approach? >> > > Your names could be better as someone mentioned. > ex, oh = 7, 13 # for example > data = [ex, ex, ex, oh, oh, oh, oh] > If you need a list distinct from the original: > try: > result = data[: data.index(oh)] > except ValueError: > result = list(data) > > Or you could simply: > try: > data = data[: data.index(oh)] > except ValueError: > pass > and data will be either the sublist you want or the original list. I forgot the obvious: result = data.count(ex) * [ex] -- -Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
I don't want to hijack the thread I was thinking whether something like lst.remove(item = 0, all = True) would be worth adding to Python? it could have this signature def remove(item, nItems = 1, all = False) ... return how_many_deleted lst.remove(item = 0, nItems = 1) lst.remove(item = 0, nItems = 2) lst.remove(item = 0, all = True) in last case nItems is ignored Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
Lonnie Princehouse wrote: > everybody is making this way more complicated than it needs to be. > > storage = list[:list.index(O)] the question is whether the old list is needed in the future or not if not then it would be easer/mor efficient to use del lst[lst.index(0):] Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
You could eliminate a few lines like this: - while list and list[0] != O: storage.append(list.pop(0)) - Adding the "list and " to the front of the logic test will catch when there are 0 elements, so the "if..break" lines are not needed. Also pop() returns the element popped, so there's no need for a separate "list[0]" and "list.pop(0)" You could also do the whole thing as a list comprehension (assuming storage is a list, otherwise += may or may not work): - storage += [i for i in list if i == X] - But this is less efficient, since it will loop through all the O's too. The other solution stops at the first O. This will also break if there are any X's mixed with O's, though you've said that's not currently the case, things can always change. Lastly, you could do this: - list.append(O) storage += list[:list.index(O)] - The first line makes sure there is always an O in list, otherwise index(O) will throw an exception. That's slightly ugly, but I still like this solution, myself. hope this helps, Jeremy -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
everybody is making this way more complicated than it needs to be. storage = list[:list.index(O)] incidentally, "list" is the name of a type, so you might want to avoid using it as a variable name. -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[...] > I have been using something like this: > _ > > while list[0] != O: > storage.append(list[0]) > list.pop(0) > if len(list) == 0: > break > _ > > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? >>> lst = [1,2,3,4,5,0,0,0,0] >>> del lst[lst.index(0):] >>> lst [1, 2, 3, 4, 5] >>> Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[...] > > What not > > for x in list: > if x == O: > break > storage.append(x) > i think this may take too long better aproach would be to test for zero from the end Regards, Daniel -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
[EMAIL PROTECTED] wrote: > Problem: > > You have a list of unknown length, such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. > > I have been using something like this: > while list[0] != O: > storage.append(list[0]) > list.pop(0) > if len(list) == 0: > break > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? > Your names could be better as someone mentioned. ex, oh = 7, 13 # for example data = [ex, ex, ex, oh, oh, oh, oh] If you need a list distinct from the original: try: result = data[: data.index(oh)] except ValueError: result = list(data) Or you could simply: try: data = data[: data.index(oh)] except ValueError: pass and data will be either the sublist you want or the original list. -- -Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
"Paul McGuire" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > <[EMAIL PROTECTED]> wrote in message > news:[EMAIL PROTECTED] > > Problem: > > > > You have a list of unknown length, such as this: list = > > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > > the X's are all up front and you know that the item after the last X is > > an O, or that the list ends with an X. There are never O's between > > X's. > > > > I have been using something like this: > > _ > > > > while list[0] != O: > > storage.append(list[0]) > > list.pop(0) > > if len(list) == 0: > > break > > _ > > > > But this seems ugly to me, and using "while" give me the heebies. Is > > there a better approach? > > > > hope this is clear. > > thanks > > > Use itertools. > > >>> import itertools > >>> lst = "X,X,X,O,O,O,O,O,X,X,X,X,O,X".split(",") > >>> [z for z in itertools.takewhile(lambda x:x=="X",lst)] > ['X', 'X', 'X'] > > > -- Paul > duh, last line should be: >>> list(itertools.takewhile(lambda x:x=="X",lst)) ['X', 'X', 'X'] (Also, don't name variables "list") -- Paul -- http://mail.python.org/mailman/listinfo/python-list
Re: is there a better way?
<[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Problem: > > You have a list of unknown length, such as this: list = > [X,X,X,O,O,O,O]. You want to extract all and only the X's. You know > the X's are all up front and you know that the item after the last X is > an O, or that the list ends with an X. There are never O's between > X's. > > I have been using something like this: > _ > > while list[0] != O: > storage.append(list[0]) > list.pop(0) > if len(list) == 0: > break > _ > > But this seems ugly to me, and using "while" give me the heebies. Is > there a better approach? > > hope this is clear. > thanks > Use itertools. >>> import itertools >>> lst = "X,X,X,O,O,O,O,O,X,X,X,X,O,X".split(",") >>> [z for z in itertools.takewhile(lambda x:x=="X",lst)] ['X', 'X', 'X'] -- Paul -- http://mail.python.org/mailman/listinfo/python-list