Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: On Oct 9, 2:31 am, Steve Holden [EMAIL PROTECTED] wrote: Keep right on guessing. I hope I'm not offending one whom I consider to be much more skilled and versed than I am, not only in python, but in programming in general; but I must say: it seems you are being rather obtuse here. I think I laid out the principal clearly enough, and I know you have the mental capacity to extrapolate from the principal to general use cases. But even so, here is a simple use case from the standard library (python 2.5 release source): In Libs/site.py, lines 302-306: try: for i in range(lineno, lineno + self.MAXLINES): print self.__lines[i] except IndexError: break With my proposal, that could be written as: for i in range(lineno, lineno + self.MAXLINES): if self.__lines.has_index(i): print self.__lines[i] else: break Granted, in this particular case the amount of code is not reduced, but (and I would hope you'd agree) the control flow is certainly easier to follow. OK, so now we appear to be arguing about whether a feature should go into Python because *you* find it to be easier to read and write. But I don't see a groundswell of support from other readers saying Wow, I've always wanted to do it like that. *Someone* (other than me!) obviously found it nice to have the dict convenience methods. As for garnishing support, I almost see that as more of a cultural, rather than pragmatic issue. I.e., if it's not there already, then it shouldn't be there: what is is what should be. Of course, consistently following that naive presumption would totally stiffle *any* extension to python. However, (I think) I do understand the psychology of the matter, and don't fault those who cannot see past what already is (not meaning to implicate you or Fredrick or anyone else -- the comment is innocent). In fact d.has_key(k) is a historical spelling, retained only for backwards compatibility, of k in dict. As to the d.get(k, default) method I really don't see a compelling use case despite your protestations, and I don't seem to be alone. Please feel free to start recruiting support. As I stated to another poster; I'm not really concerned with implementation details, only with the presence or absence of convenience methods. You can write if k in d as easily as if index len(seq). But semantically, they are similar enough, in my (admittedly lowly) estimation, to desevere similar convenience methods. The fact that nobody has listed the good reasons why I shouldn't try to make a computer from mouldy cheese doesn't make this a good idea. Heh. True. I didn't mean to imply that I was arguing from the negative. I was only tring to shift the perspective to include the reasons for the dict convenience methods. If C is good for A, and A is sufficiently similar to B, then C is good for B. But if C is just crud, then forget it all around. ;) On Oct 9, 12:24 pm, Dennis Lee Bieber [EMAIL PROTECTED] wrote: But how do you handle the case of: l = [] i = 10 l[i] = l.get(i, 0) + 1 You don't; you just let the IndexError fall through. Same as a KeyError for d[k]. My propopsal is in regard to convencience methods, not to direct access. Ps. Sorry if this comes through twice, Google is being wierd right now. I think we'll just have to agree to differ in this repsecrt, as I don't see your suggestions for extending the sequence API as particularly helpful. The one case you quote doesn't actually use the construct to supply a default value, it just terminates a loop early if the sequence length is below expectation (unless I've misread the code: that does happen). I don't really think it's a biggy, I just don't see the parallels that you do. Your point about blindness to the need for change is one that we do have to be careful of (not that I'm the person to consult about what goes into the language anyway). But if you think you've had an argument here, try writing a PEP for this and see if you can persuade the denizens of python-dev to accept (and implement) it. regard Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] But even so, here is a simple use case from the standard library (python 2.5 release source): In Libs/site.py, lines 302-306: try: for i in range(lineno, lineno + self.MAXLINES): print self.__lines[i] except IndexError: break Is there an outer loop being 'break'ed? If not, it should be pass instead. With my proposal, that could be written as: for i in range(lineno, lineno + self.MAXLINES): if self.__lines.has_index(i): print self.__lines[i] else: break This break is swallowed by the for loop, so not exactly equivalent, I think. In any case, these are both clumsy and I believe I would instead write something like for i in range(lineno, len(self.__lines)): print self.__lines[i] or even better, use islice -- for line in islice(...): print line So not a persuasive use case to me. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: In Libs/site.py, lines 302-306: try: for i in range(lineno, lineno + self.MAXLINES): print self.__lines[i] except IndexError: break With my proposal, that could be written as: for i in range(lineno, lineno + self.MAXLINES): if self.__lines.has_index(i): print self.__lines[i] else: break Granted, in this particular case the amount of code is not reduced, but (and I would hope you'd agree) the control flow is certainly easier to follow. so to improve a piece of code that's been optimized for the common case, you're adding an extra method call and a test to the inner loop? and this because you think Python programmers don't understand try- except statements ? I think we can all safely ignore you now. /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
Terry Reedy wrote: Is there an outer loop being 'break'ed? yes. This break is swallowed by the for loop, so not exactly equivalent, I think. the code is supposed to break out of the outer loop when it runs out of lines, so yes, monkeeboy's code is broken in more than one way. In any case, these are both clumsy and I believe I would instead write something like for i in range(lineno, len(self.__lines)): print self.__lines[i] that doesn't do the same thing, either. and you both seem to be missing that try: for loop over something: do something with something except IndexError: ... is a common pydiom when you expect to process quite a few somethings, and you don't want to waste time on calculating end conditions up front or checking for end conditions inside the loop or otherwise looking before you leap (LBYL); the pydiom lets you process things as quickly as you possibly can, as long as you possibly can, and deal with the end of the sequence when you hit it (EAFP*). /F *) insert martelli essay here -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
*) insert martelli essay here. for example: http://mail.python.org/pipermail/python-list/2003-May/163820.html -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 10, 1:57 am, Steve Holden [EMAIL PROTECTED] wrote: I think we'll just have to agree to differ in this repsecrt, as I don't see your suggestions for extending the sequence API as particularly helpful. No worries. :) On Oct 10, 11:22 am, Fredrik Lundh [EMAIL PROTECTED] wrote: so to improve a piece of code that's been optimized for the common case, you're adding an extra method call and a test to the inner loop? and this because you think Python programmers don't understand try- except statements ? Uh, yeah, You're all idiots and I'm not really a 'Python Programmer'(TM) -- that's exactly what I was meaning to say. I'm suprised your telepathic powers let you pick up on that, since I didn't say anything that could even remotely be construed that way. Freaky. And, FWIW, the optimized version is not much faster than that put forth by the stupid peon (me), even when my suggestion is implemented in pure python: $ cat test.py import timeit ary = ['blah'] * 10 def has_index(seq, idx): return idx len(seq) def at(seq, idx): if has_index(seq, idx): return seq[idx] def t1(): while 1: try: for i in range(11): ary[i] except IndexError: break def t2(): go = True while go: for i in range(11): if has_index(ary, i): ary[i] else: go = False def t3(): go = True while go: for i in range(11): val = at(ary, i) if val: val else: go = False print 't1 time:' print timeit.Timer('t1()', 'from __main__ import t1').timeit() print 't2 time:' print timeit.Timer('t2()', 'from __main__ import t2').timeit() print 't3 time:' print timeit.Timer('t3()', 'from __main__ import t3').timeit() $ python test.py t1 time: 15.9402189255 t2 time: 18.6002299786 t3 time: 23.2494211197 I think we can all safely ignore you now. You could have done that all along. I'm no Max Planck, and this isn't quantum mechanics. But more interesting than whether it's safe to ignore suggestions for improvement is whether its actually beneficial to do so. On Oct 10, 11:35 am, Fredrik Lundh [EMAIL PROTECTED] wrote: *) insert martelli essay here.for example: http://mail.python.org/pipermail/python-list/2003-May/163820.html I don't think this is strictly a question of EAFP vs. LBYL, but more a question of convenience. This very moment in python I can say both try: d[k] ... and if d.has_key[k] / k in d. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: On Oct 8, 3:05 pm, Steve Holden [EMAIL PROTECTED] wrote: No: you are proposing to add features to the sequence interface for which there are few demonstrable use cases. If I really wanted to find them, how many instances do you think I could find [in the standard lib and community-respected third-party libs] of sequence index checking like if 2 len(seq) and / or try-excepting like try: seq[2] ...? Judging by the fact that there isn't any other way to *safely* handle dynamic sequences (esp. sequences which grow based on side-effects which may or may not be present, depending on the execution path through the code); I'd guess the number is alot higher than you seem to think. Keep right on guessing. Well I certainly didn't find your last one particularly convincing: the attempt to reference a non-existent sequence member is almost always a programming error. Unless you are interacting with user input, or other anomalous data source. And in that case you need to do explicit index checking or wrap your code with a try...except; that or you need a convenience function or method that implements a non-terminating exception, and you just check for the exceptional case, like dictionaries have with get(). I find the latter approach to be easier to read and write (see link below), as well as understand. OK, so now we appear to be arguing about whether a feature should go into Python because *you* find it to be easier to read and write. But I don't see a groundswell of support from other readers saying Wow, I've always wanted to do it like that. I would argue exactly the opposite: the reason why they shouldn't be implemented is because no good reason has been presented why they *should*. Pretend like there are no dict.has_key and dict.get methods. Can you provide a good reason(s) why they should be implemented? Not necessity -- since you can do the same thing more verbosely. Usefulness? -- Probably; but I think the list methods would also be useful (see above). Succinctness [1]? -- The list methods have the same advantage. Anything else? [1] http://mail.python.org/pipermail/python-dev/1999-July/000594.html Nope. In fact d.has_key(k) is a historical spelling, retained only for backwards compatibility, of k in dict. As to the d.get(k, default) method I really don't see a compelling use case despite your protestations, and I don't seem to be alone. Please feel free to start recruiting support. On Oct 8, 3:11 pm, Fredrik Lundh [EMAIL PROTECTED] wrote: Huh? I don't want to treat sequences and mappings as the same thing. I'm talking about adding two similar convenience methods for sequences as already exist for mappings.so what makes you think you're the first one who's ever talked about that? I looked yesterday and only found a few posts. A couple involved Marc-Andre Lemburg, and mxTools, where he has a get() function that works for sequences and mappings; that's not what I'm suggesting. However, I found one from 1997 where he mentioned a patch to python 1.5 which added list.get, but I couldn't find the patch or any discussion of why it was (presumably) rejected. The only other post I found that was relevant was one on the dev-python list (mentioned in the July 1-15 summery [1]). And the only thing mentioned there as a reason against it is that It encourages bad coding. You shouldn't be searching lists and tuples like that unless you know what you're doing. (Whatever that is supposed to mean!). Just point me to the discussion where the good reasons (or any at all) against my suggestion can be found and I'll be glad to read it. I couldn't find it. [1] http://www.python.org/dev/summary/2006-07-01_2006-07-15/#adding-list-get-and-tuple-get The fact that nobody has listed the good reasons why I shouldn't try to make a computer from mouldy cheese doesn't make this a good idea. regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 9, 2:31 am, Steve Holden [EMAIL PROTECTED] wrote: Keep right on guessing. I hope I'm not offending one whom I consider to be much more skilled and versed than I am, not only in python, but in programming in general; but I must say: it seems you are being rather obtuse here. I think I laid out the principal clearly enough, and I know you have the mental capacity to extrapolate from the principal to general use cases. But even so, here is a simple use case from the standard library (python 2.5 release source): In Libs/site.py, lines 302-306: try: for i in range(lineno, lineno + self.MAXLINES): print self.__lines[i] except IndexError: break With my proposal, that could be written as: for i in range(lineno, lineno + self.MAXLINES): if self.__lines.has_index(i): print self.__lines[i] else: break Granted, in this particular case the amount of code is not reduced, but (and I would hope you'd agree) the control flow is certainly easier to follow. OK, so now we appear to be arguing about whether a feature should go into Python because *you* find it to be easier to read and write. But I don't see a groundswell of support from other readers saying Wow, I've always wanted to do it like that. *Someone* (other than me!) obviously found it nice to have the dict convenience methods. As for garnishing support, I almost see that as more of a cultural, rather than pragmatic issue. I.e., if it's not there already, then it shouldn't be there: what is is what should be. Of course, consistently following that naive presumption would totally stiffle *any* extension to python. However, (I think) I do understand the psychology of the matter, and don't fault those who cannot see past what already is (not meaning to implicate you or Fredrick or anyone else -- the comment is innocent). In fact d.has_key(k) is a historical spelling, retained only for backwards compatibility, of k in dict. As to the d.get(k, default) method I really don't see a compelling use case despite your protestations, and I don't seem to be alone. Please feel free to start recruiting support. As I stated to another poster; I'm not really concerned with implementation details, only with the presence or absence of convenience methods. You can write if k in d as easily as if index len(seq). But semantically, they are similar enough, in my (admittedly lowly) estimation, to desevere similar convenience methods. The fact that nobody has listed the good reasons why I shouldn't try to make a computer from mouldy cheese doesn't make this a good idea. Heh. True. I didn't mean to imply that I was arguing from the negative. I was only tring to shift the perspective to include the reasons for the dict convenience methods. If C is good for A, and A is sufficiently similar to B, then C is good for B. But if C is just crud, then forget it all around. ;) On Oct 9, 12:24 pm, Dennis Lee Bieber [EMAIL PROTECTED] wrote: But how do you handle the case of: l = [] i = 10 l[i] = l.get(i, 0) + 1 You don't; you just let the IndexError fall through. Same as a KeyError for d[k]. My propopsal is in regard to convencience methods, not to direct access. Ps. Sorry if this comes through twice, Google is being wierd right now. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Sat, 07 Oct 2006 18:06:47 -0700, MonkeeSage wrote: On Oct 7, 7:59 pm, Steven D'Aprano [EMAIL PROTECTED] wrote: Because they aren't needed often, and when they are, they are easy to implement? More often and easier to implement than dict.has_key / get? No, *less* often. That's the point -- it is fairly common for people to want dictionary lookup to return a default value, but quite rare for them to want sequence lookup to return a default value. A sequence with a default value would be, in some sense, equivalent to an infinite list: [A, B, ... , Z, default, default, default, ... ] where the A...Z are actual values. (Obviously you don't actually have an infinite list.) I can't think of any practical use for such a thing; the only thing that comes close is in some Cellular Automata it is sometimes useful to imagine cells out of range to be always in some default state. But generally speaking, you don't implement Cellular Automata with lists. It is hard to see where list.get(index, default) would be useful, since accessing an index out of range of a list is generally an error, unlike accessing a missing key. Uh, no. KeyError. dict.get() doesn't raise KeyError. That's the whole point of get(), it returns a default value instead of raising KeyError. Not every piece of functionality needs to be a built-in. Agreed. but why implement a certain functionality in one place but leave it out of another? Because implementation requires time and effort. It makes the regression tests more complicated and bloats the code base. If the feature doesn't scratch anybody's itch, if there isn't a clear use for it, it won't be implemented. If you don't care enough to even make a formal feature request, let alone a PEP, then why should people who care even less actually write the code? -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 8, 5:57 am, Steven D'Aprano [EMAIL PROTECTED] wrote: No, *less* often. That's the point -- it is fairly common for people to want dictionary lookup to return a default value, but quite rare for them to want sequence lookup to return a default value. A sequence with a default value would be, in some sense, equivalent to an infinite list: Ah, yes. Infinite dictionaries are much better! I guess you could think of it like providing a infinitely indexed list (or infinitely keyed dict), but a better way to think of it is as providing a non-terminating exception where the default value is the exceptional case. And I don't see why it would be so rare to do something like: if sys.argv.get(1): ... With list.has_index() / get(), the following (pretty common I think) idiom: try: data = some_unknown_seq[2] except IndexError: data = None if data: ... Can become: data = some_unknown_seq.get(2) if data: ... Perhaps list.get() wouldn't be used as often as dict.get(), but it would be used a fair amount I think. Looking at the standard library (2.5 source), I find 30 places where except IndexError appears, and two places where a comment says that some method raises IndexError on some condition. I haven't looked at the context of them, but I'd wager that many of them would benefit from list.has_index() and / or get(). Here is my script to search the libs: import os, re found = {} for path, dirs, files in os.walk('./Lib'): for afile in files: afile = open(os.path.join(path, afile)) lines = afile.readlines() afile.close() for line in lines: match = re.search(r'((except|raises) IndexError)', line) if match: found[afile.name] = match.group(1) for item in found.items(): print '%s (%s)' % item print 'Found %d matches' % len(found) dict.get() doesn't raise KeyError. That's the whole point of get(), it returns a default value instead of raising KeyError. Right. Exactly. Accessing a non-existent key raises a KeyError, but dict.get() short-curcuits the exception and gives you a default value (which is None unless explicitly changed). So instead of trying the key and catching a KeyError, you can use a simple conditional and ask if d.has_key(key), or assign d.get(key) and test the assignee. So, why isn't there a list.has_index() / get()? If you don't care enough to even make a formal feature request, let alone a PEP, then why should people who care even less actually write the code? I'm thinking about it. I just wanted to see if anyone knew of, or could come up with, a good reason why it isn't / shouldn't be there. Apparently not (at least not one that doesn't also bite the dict convenience methods), so I'll probably go ahead and make a feature request in the next few days. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: With list.has_index() / get(), the following (pretty common I think) idiom: try: data = some_unknown_seq[2] except IndexError: data = None if data: ... umm. you could at least write: try: data = some_unknown_seq[2] except IndexError: pass else: ... deal with data ... but let's hypergeneralize and treat sequences and mappings as the same thing proposals are nothing new; a trip to the archives might be help- ful. /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 8, 1:44 pm, Fredrik Lundh [EMAIL PROTECTED] wrote: but let's hypergeneralize and treat sequences and mappings as the same thing proposals are nothing new; a trip to the archives might be help- ful. Huh? I don't want to treat sequences and mappings as the same thing. I'm talking about adding two similar convenience methods for sequences as already exist for mappings. That may make the two APIs closer, but that's not necessarily a bad thing (think the square-bracket accessor). Besides, has_index is sufficiently different already. If it's really a problem, change get() to at() for sequences. seq.at(2). So far the reasons offered against adding those convenience methods are: Reason: It's unnecessary / bloat. - Then the same thing is true of the dict methods. Reason: It's not useful. - I know of several use cases and could probably find others. Reason: It takes effort to implement it. Why don't you do it yourself if it's such a great idea! - Mabye I will. But that is only a reason why they aren't currently implemented, not why they *shouldn't* be. Reason: It makes sequences and mapping to much alike. - Then change the names for the sequences methods. That is to say, no good reason has been offered for why these methods shouldn't be implemented. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: On Oct 8, 1:44 pm, Fredrik Lundh [EMAIL PROTECTED] wrote: but let's hypergeneralize and treat sequences and mappings as the same thing proposals are nothing new; a trip to the archives might be help- ful. Huh? I don't want to treat sequences and mappings as the same thing. I'm talking about adding two similar convenience methods for sequences as already exist for mappings. That may make the two APIs closer, but that's not necessarily a bad thing (think the square-bracket accessor). Besides, has_index is sufficiently different already. If it's really a problem, change get() to at() for sequences. seq.at(2). So far the reasons offered against adding those convenience methods are: Reason: It's unnecessary / bloat. - Then the same thing is true of the dict methods. No: you are proposing to add features to the sequence interface for which there are few demonstrable use cases. Reason: It's not useful. - I know of several use cases and could probably find others. Well I certainly didn't find your last one particularly convincing: the attempt to reference a non-existent sequence member is almost always a programming error. Reason: It takes effort to implement it. Why don't you do it yourself if it's such a great idea! - Mabye I will. But that is only a reason why they aren't currently implemented, not why they *shouldn't* be. Reason: It makes sequences and mapping to much alike. - Then change the names for the sequences methods. That is to say, no good reason has been offered for why these methods shouldn't be implemented. I would argue exactly the opposite: the reason why they shouldn't be implemented is because no good reason has been presented why they *should*. regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: but let's hypergeneralize and treat sequences and mappings as the same thing proposals are nothing new; a trip to the archives might be help- ful. Huh? I don't want to treat sequences and mappings as the same thing. I'm talking about adding two similar convenience methods for sequences as already exist for mappings. so what makes you think you're the first one who's ever talked about that? /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 8, 3:05 pm, Steve Holden [EMAIL PROTECTED] wrote: No: you are proposing to add features to the sequence interface for which there are few demonstrable use cases. If I really wanted to find them, how many instances do you think I could find [in the standard lib and community-respected third-party libs] of sequence index checking like if 2 len(seq) and / or try-excepting like try: seq[2] ...? Judging by the fact that there isn't any other way to *safely* handle dynamic sequences (esp. sequences which grow based on side-effects which may or may not be present, depending on the execution path through the code); I'd guess the number is alot higher than you seem to think. Well I certainly didn't find your last one particularly convincing: the attempt to reference a non-existent sequence member is almost always a programming error. Unless you are interacting with user input, or other anomalous data source. And in that case you need to do explicit index checking or wrap your code with a try...except; that or you need a convenience function or method that implements a non-terminating exception, and you just check for the exceptional case, like dictionaries have with get(). I find the latter approach to be easier to read and write (see link below), as well as understand. I would argue exactly the opposite: the reason why they shouldn't be implemented is because no good reason has been presented why they *should*. Pretend like there are no dict.has_key and dict.get methods. Can you provide a good reason(s) why they should be implemented? Not necessity -- since you can do the same thing more verbosely. Usefulness? -- Probably; but I think the list methods would also be useful (see above). Succinctness [1]? -- The list methods have the same advantage. Anything else? [1] http://mail.python.org/pipermail/python-dev/1999-July/000594.html On Oct 8, 3:11 pm, Fredrik Lundh [EMAIL PROTECTED] wrote: Huh? I don't want to treat sequences and mappings as the same thing. I'm talking about adding two similar convenience methods for sequences as already exist for mappings.so what makes you think you're the first one who's ever talked about that? I looked yesterday and only found a few posts. A couple involved Marc-Andre Lemburg, and mxTools, where he has a get() function that works for sequences and mappings; that's not what I'm suggesting. However, I found one from 1997 where he mentioned a patch to python 1.5 which added list.get, but I couldn't find the patch or any discussion of why it was (presumably) rejected. The only other post I found that was relevant was one on the dev-python list (mentioned in the July 1-15 summery [1]). And the only thing mentioned there as a reason against it is that It encourages bad coding. You shouldn't be searching lists and tuples like that unless you know what you're doing. (Whatever that is supposed to mean!). Just point me to the discussion where the good reasons (or any at all) against my suggestion can be found and I'll be glad to read it. I couldn't find it. [1] http://www.python.org/dev/summary/2006-07-01_2006-07-15/#adding-list-get-and-tuple-get Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
At Saturday 7/10/2006 02:15, MonkeeSage wrote: On Oct 6, 8:23 pm, Gabriel Genellina [EMAIL PROTECTED] wrote: if 2 in [1,2,3]: print Use the same (in) operator elif 'E' in ('E','r','i','k'): print Works for any sequence elif 'o' in 'hello': print Even strings This isn't really analogous is it? For somedict.has_key(k) or k in somedict, you don't need to know the value of somedict[k] ahead of time. So you can avoid KeyError by asking if the key exists first before trying to get the value. The meaning comes from the most common usage. For a list, you want to know if an object is contained in the list (not if an index is in range!). For a dictionary, you usually want to know if it maps anything to a given key (not if any key maps to that value!). These are the most common operations, and that's why they have the simple sintax a in b. [BTW, usage of operator in as key in dict is rather new to Python; has_key() were the only way to test for key existence some time ago]. Wouldn't that be more like this for lists (and other sequences): def has_index(seq, index): try: seq[index] return True except IndexError: return False I've often wondered why there is no built-in method like that for sequence objects. Because it's not needed at all: valid sequence indexes are *exactly* range(len(seq)). This is the basic point of being a sequence: when indexes are not contiguous, in fact you have a mapping, not a sequence. And also why not the equivalent of dict.get for other sequences: def get(seq, index, default=None): if has_index(seq, index): return seq[index] else: return default Seems useful... Sometimes, maybe... But since you can write it efficientely in a few lines when needed, I don't see the need to put it into the core language. -- Gabriel Genellina Softlab SRL __ Preguntá. Respondé. Descubrí. Todo lo que querías saber, y lo que ni imaginabas, está en Yahoo! Respuestas (Beta). ¡Probalo ya! http://www.yahoo.com.ar/respuestas -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 7, 3:27 am, Gabriel Genellina [EMAIL PROTECTED] wrote: The meaning comes from the most common usage. I wasn't suggesting that the in keyword have a different sematic for sequence types. I was just saying that regarding the question whether there is anything similar to dict.has_key / k in dict for lists, the in keyword is not semantically analogous. Because it's not needed at all: valid sequence indexes are *exactly* range(len(seq)). This is the basic point of being a sequence: when indexes are not contiguous, in fact you have a mapping, not a sequence. True. But valid dictionary keys are exactly d.keys(). The has_key method is just sugar. Sometimes, maybe... But since you can write it efficientely in a few lines when needed, I don't see the need to put it into the core language. Couldn't the same be said for dictionaries? I could write for sequences: if index len(seq) and seq[index]: ... But I could also write for dictionaries: if key in dic.keys() and dic[key]: ... I just wonder why the syntactic sugar was added for dicts, but not for sequence types. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: True. But valid dictionary keys are exactly d.keys(). The has_key method is just sugar. for what? are you sure you're using sugar as it is usually used when talking about computer languages? /F -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 7, 12:37 pm, Fredrik Lundh [EMAIL PROTECTED] wrote: for what? key in self.keys() And d.get() looks like sugar for: if self.has_key(key): return self[key] else: return default_value Why not have the same sugar for sequence types? E.g., def has_index(self, index): return index len(self) def get(self, index, default=None): if self.has_index(index): return self[index] return default I understand not wanting to add bloat without use cases and / or when the programmer can easily implement the functionality themselves; but I don't see why the sugar would be added for dict but not sequence types. The fact of easy implementation by the programmer without the convenience method is the same in both cases, and I would assume (but don't claim to know) that one could find many use cases for, e.g., list.has_index() / . get(). Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: On Oct 7, 12:37 pm, Fredrik Lundh [EMAIL PROTECTED] wrote: for what? key in self.keys() [snip] No. The above constructs a list of keys and searches the list for the key, O(n). key in somedict is a lookup, O(1). Duncan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 7, 7:14 pm, Duncan Smith [EMAIL PROTECTED] wrote: No. The above constructs a list of keys and searches the list for the key, O(n). key in somedict is a lookup, O(1). My point wasn't in regard to implementation details, but in regard to convenience methods. Obviously the sugary dict methods are tweaked for the best performance (one would hope!), as would be sugary sequence methods were they to be added. What I was wondering is why dict.has_key() and get() are there but not list.has_index() and get(). Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Sat, 07 Oct 2006 10:26:22 -0700, MonkeeSage wrote: On Oct 7, 3:27 am, Gabriel Genellina [EMAIL PROTECTED] wrote: The meaning comes from the most common usage. I wasn't suggesting that the in keyword have a different sematic for sequence types. I was just saying that regarding the question whether there is anything similar to dict.has_key / k in dict for lists, the in keyword is not semantically analogous. Are you just making a philosophical point? In which case I agree: *if* you make the analogy a dictionary key is analogous to a sequence index, *then* the operation of in isn't semantically analogous between mappings and sequences. But why should it be? In both mappings and sequences, in tests for membership. But *what* it tests for membership is different. There's no shame there. Because it's not needed at all: valid sequence indexes are *exactly* range(len(seq)). This is the basic point of being a sequence: when indexes are not contiguous, in fact you have a mapping, not a sequence. True. But valid dictionary keys are exactly d.keys(). The has_key method is just sugar. A little bit of history might be useful here. Originally, if you wanted to test for key membership with a dict, you had three choices: (1) Easier To Ask Forgiveness Than Permission: try: mapping[key] except KeyError: print Oops, that's not a key! (2) mapping.has_key(key), which inspected the dict's internals to determine whether key was valid or not. (3) Build a list of keys, then test whether the key was in the list: key in mappings.keys() Obviously all three methods had their disadvantages. The first required catching an exception, which is expensive, and is less than clear. The second is a magic method that needs to be remembered by the developer, and breaks the equivalence of mappings and sequences. The third means building, and throwing away, a temporary list of keys. But after types and classes were unified, dicts grew a __contains__ method for subclassing. If you want syntactic sugar, x in obj is just syntactic sugar for obj.__contains__(x) (but note the scare quotes around just: one person's syntactic sugar is another person's essential syntactic feature). -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Sat, 07 Oct 2006 17:25:15 -0700, MonkeeSage wrote: My point wasn't in regard to implementation details, but in regard to convenience methods. Obviously the sugary dict methods are tweaked for the best performance (one would hope!), as would be sugary sequence methods were they to be added. What I was wondering is why dict.has_key() and get() are there but not list.has_index() and get(). Because they aren't needed often, and when they are, they are easy to implement? Instead of list.has_index(n), write 0 = n len(list). If you want to allow for negative indices as well, write -len(list) = n len(list). It is hard to see where list.get(index, default) would be useful, since accessing an index out of range of a list is generally an error, unlike accessing a missing key. But I like symmetry, and for symmetry I wouldn't object to sequences gaining a get method too. Not that I care about it enough to put in a feature request or a PEP, but if somebody else did, I wouldn't object. (Note, though, that accessing a *slice* out of range is not an error, but returns an empty list.) get() is easy enough to implement. Feel free to turn it into a method of a collection class if you like. def get(mapping_or_sequence, key_or_index, default=None): try: return mapping_or_sequence.get(key_or_index, default) except AttributeError: # probably a sequence try: return mapping_or_sequence[key_or_index] except IndexError: return default Not every piece of functionality needs to be a built-in. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 7, 7:41 pm, Steven D'Aprano [EMAIL PROTECTED] wrote: Are you just making a philosophical point? In which case I agree: *if* you make the analogy a dictionary key is analogous to a sequence index, *then* the operation of in isn't semantically analogous between mappings and sequences. But why should it be? It shouldn't, and I'm making a pragmatic (not merely philosophic) point regarding the OP's question whether there is a similar list method to dict.has_key. In both mappings and sequences, in tests for membership. But *what* it tests for membership is different. There's no shame there. I know / agree. Originally, if you wanted to test for key membership with a dict, you had three choices: I know. On Oct 7, 7:59 pm, Steven D'Aprano [EMAIL PROTECTED] wrote: Because they aren't needed often, and when they are, they are easy to implement? More often and easier to implement than dict.has_key / get? It is hard to see where list.get(index, default) would be useful, since accessing an index out of range of a list is generally an error, unlike accessing a missing key. Uh, no. KeyError. But I like symmetry, and for symmetry I wouldn't object to sequences gaining a get method too. Not that I care about it enough to put in a feature request or a PEP, but if somebody else did, I wouldn't object. Me neither. :) get() is easy enough to implement. Feel free to turn it into a method of a collection class if you like. I already did, see previous posts. Not every piece of functionality needs to be a built-in. Agreed. but why implement a certain functionality in one place but leave it out of another? Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
MonkeeSage wrote: On Oct 7, 7:14 pm, Duncan Smith [EMAIL PROTECTED] wrote: No. The above constructs a list of keys and searches the list for the key, O(n). key in somedict is a lookup, O(1). My point wasn't in regard to implementation details, but in regard to convenience methods. Obviously the sugary dict methods are tweaked for the best performance (one would hope!), as would be sugary sequence methods were they to be added. What I was wondering is why dict.has_key() and get() are there but not list.has_index() and get(). Regards, Jordan All I can say is that, I personally, would have little use for those list methods. Those involved in the design of the language will no doubt have much better reasons than this. Duncan -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 7, 8:06 pm, MonkeeSage [EMAIL PROTECTED] wrote: More often and easier to implement than dict.has_key / get? More - Less -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
I ended up using len(sys.argv) 1 for this particular problem. But I think slicing is closer to the tool I was looking for. I found a.has_key(k) or k in a for dictionaries - but haven't found anything similar for lists. Does it exist? I guess my example from php would technically be a dictionary in python and not a list, it would nice to be able to quickly tell if a list key existed or not. Thanks! Erik Steve Holden wrote: [EMAIL PROTECTED] wrote: Hi all, I'm sorry about the newbie question, but I've been searching all afternoon and can't find the answer! I'm trying to get this bit of code to work without triggering the IndexError. import shutil, os, sys if sys.argv[1] != None: ver = sys.argv[1] else: ver = '2.14' Of course, whenever I run it, I get list index out of range. I'm coming from the php world where I can do: if $_GET['var'] != Null { $ver = $_GET['var']; } else { $ver = '2.14'; } Can anyone tell me how to make this work in python? Well all the advice you've had so far seems good, but of course the simplest way is just to test the length of the sequence before you try to address its second element: if len(sys.argv) 1: ver = sys.argv[1] else: ver = 2.14 regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
At Friday 6/10/2006 20:57, erikcw wrote: I ended up using len(sys.argv) 1 for this particular problem. But I think slicing is closer to the tool I was looking for. I found a.has_key(k) or k in a for dictionaries - but haven't found anything similar for lists. Does it exist? if 2 in [1,2,3]: print Use the same (in) operator elif 'E' in ('E','r','i','k'): print Works for any sequence elif 'o' in 'hello': print Even strings Gabriel Genellina Softlab SRL __ Preguntá. Respondé. Descubrí. Todo lo que querías saber, y lo que ni imaginabas, está en Yahoo! Respuestas (Beta). ¡Probalo ya! http://www.yahoo.com.ar/respuestas -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On 6 Oct 2006 16:57:23 -0700, erikcw [EMAIL PROTECTED] wrote: I ended up using len(sys.argv) 1 for this particular problem. But I think slicing is closer to the tool I was looking for. I found a.has_key(k) or k in a for dictionaries - but haven't found anything similar for lists. Does it exist? As Gabriel Genellina observed, lists also may use the 'in' syntax. Actually, any object that supports the method __contains__ can do this, which means you may furnish your own in user objects. What hasn't been addressed is efficiency. This is often a secondary concern in a VHLL such as Python, but you may wish to know that using the 'in' test on a large list repeatedly will slow down a program. You may wish to use a set object instead, according to the application. I guess my example from php would technically be a dictionary in python and not a list, it would nice to be able to quickly tell if a list key existed or not. Yes, PHP arrays are associative (dicts). But lists (in the Pythonic sense, aka 'vectors') do not have keys as such, only indices. -- Theerasak -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
On Oct 6, 8:23 pm, Gabriel Genellina [EMAIL PROTECTED] wrote: if 2 in [1,2,3]: print Use the same (in) operator elif 'E' in ('E','r','i','k'): print Works for any sequence elif 'o' in 'hello': print Even strings This isn't really analogous is it? For somedict.has_key(k) or k in somedict, you don't need to know the value of somedict[k] ahead of time. So you can avoid KeyError by asking if the key exists first before trying to get the value. Wouldn't that be more like this for lists (and other sequences): def has_index(seq, index): try: seq[index] return True except IndexError: return False I've often wondered why there is no built-in method like that for sequence objects. And also why not the equivalent of dict.get for other sequences: def get(seq, index, default=None): if has_index(seq, index): return seq[index] else: return default Seems useful... Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Can't get around IndexError: list index out of range
Hi all, I'm sorry about the newbie question, but I've been searching all afternoon and can't find the answer! I'm trying to get this bit of code to work without triggering the IndexError. import shutil, os, sys if sys.argv[1] != None: ver = sys.argv[1] else: ver = '2.14' Of course, whenever I run it, I get list index out of range. I'm coming from the php world where I can do: if $_GET['var'] != Null { $ver = $_GET['var']; } else { $ver = '2.14'; } Can anyone tell me how to make this work in python? Thanks! Erik -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
[EMAIL PROTECTED] wrote: I'm trying to get this bit of code to work without triggering the IndexError. import shutil, os, sys if sys.argv[1] != None: ver = sys.argv[1] else: ver = '2.14' Catch it: try: ver = sys.argv[1] except IndexError: ver = '2.14' -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
[EMAIL PROTECTED] wrote: I'm trying to get this bit of code to work without triggering the IndexError. import shutil, os, sys if sys.argv[1] != None: ver = sys.argv[1] else: ver = '2.14' Something like:: if len(sys.argv) 1: ver = sys.argv[1] else: ver = '2.14' It looks like you're trying to do argument parsing, though and for anything more complicated than the above, you might prefer to use a real argument parsing library like argparse_:: import argparse parser = argparse.ArgumentParser(description='print the version') parser.add_argument('ver', nargs='?', default='2.14', help='the version number to print') args = parser.parse_args() print args.ver Then from the command line:: $ script.py 2.14 $ script.py 3.14159265359 3.14159265359 $ script.py -h usage: script.py [-h] [ver] print the version positional arguments: ver the version number to print optional arguments: -h, --help show this help message and exit And then you can feel good about yourself for also documenting your command-line interface. ;-) .. _argparse: http://argparse.python-hosting.com/ STeVe -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
Leif K-Brooks [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] [EMAIL PROTECTED] wrote: I'm trying to get this bit of code to work without triggering the IndexError. import shutil, os, sys if sys.argv[1] != None: ver = sys.argv[1] else: ver = '2.14' Catch it: try: ver = sys.argv[1] except IndexError: ver = '2.14' Or slice it: if sys.argv[1:2] != []: etc tjr -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
Terry Reedy wrote bloated code: if sys.argv[1:2] != []: if sys.argv[1:2]: :-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Can't get around IndexError: list index out of range
[EMAIL PROTECTED] wrote: Hi all, I'm sorry about the newbie question, but I've been searching all afternoon and can't find the answer! I'm trying to get this bit of code to work without triggering the IndexError. import shutil, os, sys if sys.argv[1] != None: ver = sys.argv[1] else: ver = '2.14' Of course, whenever I run it, I get list index out of range. I'm coming from the php world where I can do: if $_GET['var'] != Null { $ver = $_GET['var']; } else { $ver = '2.14'; } Can anyone tell me how to make this work in python? Well all the advice you've had so far seems good, but of course the simplest way is just to test the length of the sequence before you try to address its second element: if len(sys.argv) 1: ver = sys.argv[1] else: ver = 2.14 regards Steve -- Steve Holden +44 150 684 7255 +1 800 494 3119 Holden Web LLC/Ltd http://www.holdenweb.com Skype: holdenweb http://holdenweb.blogspot.com Recent Ramblings http://del.icio.us/steve.holden -- http://mail.python.org/mailman/listinfo/python-list