Re: len() should always return something
On Friday 24 July 2009 11:58:36 am Phillip M. Feldman wrote: I've been converting Matlab codes to Python. In Matlab, a scalar is just a one-by-one matrix and has a length of 1. This convention seems no less arbitrary to me than Python's convention that the concept of length is not applicable to ints and floats. Are you sure it isn't? (as opposed to being tainted by matlab?). Almost everywhere, a scalar and a tuple are different things. How many elements are inside the number 7? If you assume that 7 is a matrix, why should it be a two-dimensional matrix? Why not a vector, or a three dimensional matrix instead? (I don't use matlab, but in octave, size(7) returns [1,1], not [1] or [1,1,1,1]). That seems even more arbitrary to me. Of course, in a language like Matlab, that assumes that everything is a matrix, it makes sense for scalars to be mapped to a useful matrices. But that assumption is not natural. Even pure math makes a difference between scalars and vectors. Matrix x Matrix multiplication is not always defined (even when the second matrix contains exactly one element), while Matrix x Scalar always is. (Octave, btw, will demote a two-dimensional 1x1 matrix to a scalar for Matrix multiplication, which may hide errors) If you are converting from matlab, I'd say you have biggest things to worry about. As you said, you can just replace the len function (even safer may be to do [1]). Assignment, for instance, is /very/ different. If there is only a single measurement, it is reasonable to allow the calling program to pass a scalar without wrapping it up into a list or array. I try to avoid those automatic conversions, on the long run, I believe that most of them make the code more confusing for the caller. If you feel that you must allow that, my suggestion would be to create a method that will ensure that what you receive is a list (or whatever) and coerce its argument if not, and call that one at the beginning of your methods. Regards, [1] this will define len for any object, not only int and floats. === def size(x): try: return len(x) except TypeError: return 1,1 === -- Luis Zarrabeitia (aka Kyrie) Fac. de Matemática y Computación, UH. http://profesores.matcom.uh.cu/~kyrie -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Dr. Phillip M. Feldman wrote: As far as I know, there is no programming language which treats scalars like ints as if they were vectors of length 1 Actually, Matlab does: length(5) ans = 1 Oddly enough, so does Perl: $ print length(44) 2 (that's in the Zoidberg shell) j -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On 2009-07-27, Joshua Kugler jos...@joshuakugler.com wrote: Dr. Phillip M. Feldman wrote: As far as I know, there is no programming language which treats scalars like ints as if they were vectors of length 1 Actually, Matlab does: length(5) ans = 1 Oddly enough, so does Perl: $ print length(44) 2 No, that's not really treating scalars as vectors of length 1. Were it doing so, length(44) would be 1 rather than 2. What Perl does is treat everything as a string. -- Grant Edwards grante Yow! I was making donuts at and now I'm on a bus! visi.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Dr. Phillip M. Feldman pfeld...@verizon.net wrote in message news:mailman.3699.1248490256.8015.python-l...@python.org... Here's a simple-minded example: ... This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: Wow, you could substitute Matlab for Python in your post and it'd still be just as good. :-) -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sunday 26 July 2009 00:42:26 Marcus Wanner wrote: On 7/25/2009 10:08 AM, Piet van Oostrum wrote: Steven D'Aprano st...@remove-this-cybersource.com.au (SD) wrote: SD Ambiguity essentially boils down to being unable to reasonably predict SD the expectation of the coder. I say reasonably, because if you allow SD unreasonable situations, everything is ambiguous: That's for me the reason that len(42) is ambiguous. The OP apparently had 1 as expectation, whereas my first thought was the minimal number of bits to represent the number and 7.5 million came later :=). The number of bits I certainly find reasonable, and I would find the number of decimal digits equally reasonable. More so than 1, actually. 1 as the length of an int doesn't give any information. Well, for my two cents, I will say that the number of binary bits or decimal digits is certainly the most sensible return value, and that the former is the most useful, because the latter can be got with len(str(42)). However, the former can also be (/slightly/ less)easily got with len(bin(42))-2... For my two eurocents, I'd expect such an operator to be called sizeof and when applied to a collection, to also return the number of bits it uses. I don't think a 'len' function has meaning when applied to something else than a collection, really... I also think that Explicit is better than implicit. says that there should be no return value in this case, as any return value would be implicit. Agreed. Cheers, Emm -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sat, 25 Jul 2009 16:21:39 -0700, Erik Max Francis wrote: Steven D'Aprano wrote: But it's not practically every function. It's hardly any function at all -- in my code, I don't think I've ever wanted this behavior. I would consider it an error for function(42) and function([42]) to behave the same way. One is a scalar, and the other is a vector -- they're different things, it's poor programming practice to treat them identically. (If Matlab does this, so much the worse for Matlab, in my opinion.) There's actually good reason to do this in heavily matrix-oriented specialized languages; there are numerous applications where scalars and 1x1 matrices are mathematically equivalent. I'm curious what those applications are, because regular multiplication behaves differently depending on whether you have a 1x1 matrix or a scalar: [[2]]*[[1, 2, 3], [2, 3, 4]] is not defined 2*[[1, 2, 3], [2, 3, 4]] = [[2, 4, 6], [2, 6, 8]] I'm curious as to what these applications are, and what they're actually doing. Kronecker multiplication perhaps? Do you have some examples of those applications? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Steven D'Aprano wrote: I'm curious what those applications are, because regular multiplication behaves differently depending on whether you have a 1x1 matrix or a scalar: [[2]]*[[1, 2, 3], [2, 3, 4]] is not defined 2*[[1, 2, 3], [2, 3, 4]] = [[2, 4, 6], [2, 6, 8]] I'm curious as to what these applications are, and what they're actually doing. Kronecker multiplication perhaps? Do you have some examples of those applications? The most obvious example would be the matrix algebra equivalent of the calculation of the dot product, the equivalent of a dot product in normal vector algebra. If you have two 3-vectors (say), u = (u_1, u_2, u_3) and v = (v_1, v_2, v_3), then the dot product is the sum of the pairwise products of these terms, u dot v = sum_i u_i v_i = u_1 v_1 + u_2 v_2 + u_3 v_3. Nothing revolutionary there. The matrix way of writing this wouldn't obviously work, since multiplying two nx1 or (1xn) matrixes by each other is invalid. But you _can_ multiply a nx1 matrix by an 1xn matrix, and you get the equivalent of the dot product: u v^T = ( u dot v ), where the right hand side of the equation is formally a 1x1 matrix (intended to be indicated by the parentheses), but you can see how it is useful to think of it as just a scalar, because it's really just a matrix version of the same thing as a dot product. This stretches out to other kinds of applications, where, say, in tensor calculus, you can think of a contravariant vector as being transformed into a covariant vector by the application of the matrix tensor, which is written as lowering an index. The components of the contravariant vector can be thought of as a column vector, while the components of a covariant vector can be represented with a row vector. The application of the metric tensor to a contravariant vector turns it into a row vector, and then contracting over the two vectors gives you the inner product as above. The applications and contractions can all be visualized as matrix multiplications. (Contrary to a popularization, tensors _aren't_ generalizations of matrices, but their components can be.) It's a bunch of other examples like that where you end up with a 1x1 matrix that really represents a scalar, and since that was intended there really isn't a lot of efficacy to treat it as a separate entity. Especially if you're dealing with a special-purpose language where everything is really a form of an generalized array representation of something _anyway_. -- Erik Max Francis m...@alcyone.com http://www.alcyone.com/max/ San Jose, CA, USA 37 18 N 121 57 W AIM/Y!M/Skype erikmaxfrancis Scars are like memories. We do not have them removed. -- Chmeee -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
To the best of my recollection, the len() function only applies to container objects; i. e. tuples, lists, strings, etc. an integer object is not a container, thus one receives an error when sending an int as an argument for len(). -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sat, Jul 25, 2009 at 4:50 AM, Dr. Phillip M. Feldmanpfeld...@verizon.net wrote: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. I don't have this problem - when I have a list of one element, that's what I use - a list with one element. I think things would get much simpler if you do such a conversion right at the Matlab-Python interface, rather than changing all kind of things in Python so that its types are more matlab-like. Just like you shouldn't program Python by simply translating Java or C into Python idiom, you also shouldn't program Python by trying to mimic Matlab. Each language has its own strengths and weaknesses, and moving things over too much in a simplistic fashion will usually mean that you get the weaknesses of both and the strengths of neither. -- André Engels, andreeng...@gmail.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, 24 Jul 2009 19:50:54 -0700, Dr. Phillip M. Feldman wrote: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. But it's not practically every function. It's hardly any function at all -- in my code, I don't think I've ever wanted this behavior. I would consider it an error for function(42) and function([42]) to behave the same way. One is a scalar, and the other is a vector -- they're different things, it's poor programming practice to treat them identically. (If Matlab does this, so much the worse for Matlab, in my opinion.) However, if you want this behaviour, it's easy enough to get it with a decorator: from functools import wraps def matlab(func): Decorate func so that it behaves like Matlab, that is, it considers a single scalar argument to be the same as a vector of length one. @wraps(func) def inner(arg, **kwargs): # If arg is already a vector, don't touch it. try: # If this succeeds, it's a vector of some type. iter(arg) except TypeError: # It's a scalar. arg = [arg] # Now call the decorated function (the original). return func(arg, **kwargs) return inner With this decorator in hand, you can now easily get the behaviour you want with a single extra line per function: @matlab ... def mean(numbers): ... return sum(numbers)/len(numbers) ... mean([4.5]) 4.5 mean(4.5) 4.5 mean([4.5, 3.6]) 4.0498 Decorators are extremely powerful constructs, and well worth learning. As an example, here's a similar decorator that will accept multiple arguments, like the built-in functions min() and max(): def one_or_many(func): Decorate func so that it behaves like the built-ins min() and max(). @wraps(func) def inner(*args, **kwargs): # If we're given a single argument, and it's a vector, # use it as args. if len(args) == 1: try: iter(args[0]) except TypeError: pass else: # No exception was raised, so it's a vector. args = args[0] # Now call the decorated function (the original). return func(args, **kwargs) return inner And then use it: @one_or_many ... def minmax(numbers): ... Return the minimum and maximum element of numbers, ... making a single pass. ... # the following will fail if given no arguments ... smallest = biggest = numbers[0] ... for x in numbers[1:]: ... if x smallest: ... smallest = x ... elif x biggest: ... biggest = x ... return (smallest, biggest) ... minmax([2, 4, 6, 8, 1, 3, 5, 7]) (1, 8) minmax(2, 4, 6, 8, 1, 3, 5, 7) (1, 8) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Friday 24 July 2009 16:45:40 Mark Dickinson wrote: On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk wrote: Which doesn't make your point less valid. In fact I'd go so far as to argue that what len() gives you is the number of items in a container, so len(7) should return 0. Nah. 7 contains three bits, so len(7) should *clearly* return 3. Almost right - however the first seven that you typed was a string seven and not an int - so the hex is 37 and that takes at least six bits... :-) Now if only someone can figure out a reason why it should return seven, then it would be perfect! - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Jul 23, 11:35 pm, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x): if isinstance(x,int) or isinstance(x,float): return 1 return len(x) But, this shouldn't be necessary. I knew that you were coming from Matlab as soon as I saw the subject line. I use both Matlab and Python very often, and I understand the design decisions behind both (insofar as Matlab can be considered a design). The thing to keep in mind about Python is that it's a general purpose language, not just for mathematical computation, and there are some things in Python that are a bit suboptimal for math calculations. This is one of them: when the types of objects you are dealing with most often are numbers, then there's not much chance for ambiguity when treating a scalar as a 1x1 matrix. However, when doing general purpose programming, you often use lots of types besides numbers, some of which are containers themselves. This creates the possibility of ambiguity and inconsistent behavior. Let's consider your example function. def dumbfunc(xs): for x in xs: print x You can use it on an list, like this, and there is no ambiguity: dumbfunc([1,2,3]) Now suppose Python allowed numbers to be treated as degenerate sequences of length 1. Then you could pass a number, and it would work as you expect: dumbfunc(1) However, because Python is general purpose, you might also want to pass other types around, such as strings. Say you wanted to print a list of string, you would do this, and it would work as expected: dumbfunc([abc,def,ghi]) Now, the problem. In the numbers example, you were able to treat a single number as a degenerate list, and by our supposition, it worked. By analogy, you would expect to be able to do the same with a list of strings, like this: dumbfunc(abc) Whoops: doesn't work. Instead of printing one string abc it prints three strings, a, b, and c. By allowing scalar numbers to act as degenerate lists, you've introduced a very bad inconsistency into the language, you've made it difficult to learn the language by analogy. For a general purpose language there is really no second-guessing this design decision. It would be unequivocally bad to have atomic types act like sequences. The reason it isn't so bad in Matlab is that you can rely on the elements of an array to be scalar. Matlab, for its part, does contain some types (cell arrays and structures) that can contain non-scalars for cases when you want to do that. However, you will notice that no scalar will ever be treated as a degenerate cell array or structure. Even a poorly designed, ad hoc language like Matlab won't try to treat scalar numbers as cell arrays, because ambiguity like I described above will appear. Nope, it takes an abomination like Perl to do that. As for how I would recommend you translate the Matlab function that rely on this: you need to decide whether that scalar number you are passing in is REALLY a scalar, or a degenerate vector. If it's the latter, just get over it and pass in a single-item list. I have done these kinds of conversions myself before, and that's the way to do it. Trying to be cute and writing functions that can work with both types will lead to trouble and inconsistency, especially if you are a Python newbie. Just pass in a list if your function expects a list. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Dr. Phillip M. Feldman schrieb: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. And where comes len(xs) into play here? What you want is iteration over scalars. I do think that if you frequently have to write code like that, you are writing errorneous code. But might that as it is, a simple def iterable(i): if isinstance(i, (int, float, complex)): return [i] return i is all you need. So you can write for x in iterable(xs): wherever you expect values to be either scalar or iterable. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Steven D'Aprano st...@remove-this-cybersource.com.au (S) wrote: S Chris, I'm curious why you think that these Zen are relevant to the OP's S complaint. S Re explicit vs implicit, len(42) is just as explicit as len([42, 23]). S Arguably (I wouldn't argue this, but some people might) ints aren't S special enough to break the rule that len(obj) should always return S something. S (I don't actually agree, but some people might be able to produce a S coherent argument why len() should apply equally to all objects.) S Re errors passing silently, the OP doesn't believe that len(42) should be S an error, so that's not relevant. S And there's nothing ambiguous about len(42). len(42) should be 7.5 million. -- Piet van Oostrum p...@cs.uu.nl URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4] Private email: p...@vanoostrum.org -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Friday 24 July 2009 21:04:55 Roy Smith wrote: Compressing strings to a single bit is easy. It's the uncompressing that's tricky. Not really - all you have to do is to apply the EXACT same sequence of operations that compressed it, in reverse. The unfortunate part is that this information is in almost all cases larger than the original, uncompressed string, so that it kind of defeats the object of compression. So yes - tricky! :-) - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Friday 24 July 2009 22:09:15 Marcus Wanner wrote: First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p that is easy. the xor of 0 and 1 is 1, which is ASCII soh, if I remember right. soh is start of header. Burroughs poll select, anyone? - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On 7/25/2009 5:34 AM, Hendrik van Rooyen wrote: On Friday 24 July 2009 22:09:15 Marcus Wanner wrote: First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p that is easy. the xor of 0 and 1 is 1, which is ASCII soh, if I remember right. soh is start of header. Burroughs poll select, anyone? - Hendrik nope, not soh. Marcus -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sat, 25 Jul 2009 10:03:58 +0200, Piet van Oostrum wrote: S And there's nothing ambiguous about len(42). len(42) should be 7.5 million. And I don't understand your reasoning.upper() should be Millennium Hand and Shrimp!. Every function would be ambiguous if we treat it as returning an arbitrary result. But we don't -- semantics do matter. We expect that string.upper() should return the string converted to uppercase, and that's not ambiguous because we already know what uppercase means. Even if somebody didn't know what uppercase meant, they would expect that it had a meaning, and it was just a matter of learning what it meant: for example, one might take string.upper() as any of: * convert every letter a..z to A..Z * convert the first letter of each word to A..Z * throw away the argument and return the literal upper * count how many characters are in A..Z and so forth. These are some of the infinite number of *possible* meanings to string.upper(), but only one of them is the *actual* meaning. The method isn't ambiguous, because the language designers have chosen one meaning, and having learned what that meaning is, it's the *only* meaning you can legitimately use. If you (generic you) are uncertain what that meaning is, that's uncertainty, not ambiguity. Similarly, we might be uncertain about the meaning of len(42) -- reasonable values it might return are 0, 1, 2, the number of bits in 42, and possibly even 7.5 million as you suggest. But that's our ignorance, due to the fact that we haven't yet agreed on a meaning to len(42), and not ambiguity: having made up our mind what len(42) should mean, it could only mean one thing. However, mixed string/integer addition is a good example of ambiguity. We can add strings: 1 + 2 = 12 and we can add integers: 1 + 2 = 3 but it is ambiguous as to what 1 + 2 should return. Guido might have made Python behave like Perl, and define addition of a string and an int, but there would still be ambiguity in the expression, because we can't tell if the coder intended 1+2 and forgot to quote the two, or intended 1+2 and forgot to convert the string 1 to an int. Ambiguity essentially boils down to being unable to reasonably predict the expectation of the coder. I say reasonably, because if you allow unreasonable situations, everything is ambiguous: I typed: x = 42 + y but maybe I intended to import the math module, therefore the + operator is ambiguous. Reasonable? No, because we're allowed to assume the coder is rational, and mistakes are small. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Steven D'Aprano st...@remove-this-cybersource.com.au (SD) wrote: SD Ambiguity essentially boils down to being unable to reasonably predict SD the expectation of the coder. I say reasonably, because if you allow SD unreasonable situations, everything is ambiguous: That's for me the reason that len(42) is ambiguous. The OP apparently had 1 as expectation, whereas my first thought was the minimal number of bits to represent the number and 7.5 million came later :=). The number of bits I certainly find reasonable, and I would find the number of decimal digits equally reasonable. More so than 1, actually. 1 as the length of an int doesn't give any information. -- Piet van Oostrum p...@cs.uu.nl URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4] Private email: p...@vanoostrum.org -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Saturday 25 July 2009 14:59:43 Steven D'Aprano wrote: On Sat, 25 Jul 2009 10:03:58 +0200, Piet van Oostrum wrote: S And there's nothing ambiguous about len(42). len(42) should be 7.5 million. And I don't understand your reasoning.upper() should be Millennium Hand and Shrimp!. That does it. I will be kinder to you in future. Anybody who quotes foul old Ron cannot be all bad. - Hendrik -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sat, 25 Jul 2009 03:50:54 +0100, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. If you persist in treating language 1 as if it was language 2, then your code will always be ugly, and often buggy. Unless we're talking natural languages, in which case Yoda-like you will sound. Fundamentally, your problem is your assertion that it is reasonable to allow users to treat a single object as if it were wrapped in a list. In Python, it is not reasonable, for the reasons that you are spending so much time complaining about. -- Rhodri James *-* Wildebeest Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On 2009-07-24 21:50, Dr. Phillip M. Feldman wrote: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. I have spent the last ten years writing scientific code in Python (i.e. that which otherwise might be written in Matlab), and I can guarantee you that you do not need to put such extra logic in practically every function. Even when naively translating code from Matlab, it's not often necessary. By the way, are you familiar with numpy? If you are converting code from Matlab, you will almost certainly need it. We have a number of functions that make these kinds of operations easy when they are in fact necessary. For example, we have isscalar() and atleast_1d(). def dumbfunc(xs): xs = numpy.atleast_1d(xs) for x in xs: print x http://numpy.scipy.org/ -- 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: len() should always return something
On 2009-07-25 02:55, Diez B. Roggisch wrote: Dr. Phillip M. Feldman schrieb: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. And where comes len(xs) into play here? What you want is iteration over scalars. He explained in another post that iteration is another feature along the same lines that he would want for scalars. -- 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: len() should always return something
On 7/25/2009 10:08 AM, Piet van Oostrum wrote: Steven D'Aprano st...@remove-this-cybersource.com.au (SD) wrote: SD Ambiguity essentially boils down to being unable to reasonably predict SD the expectation of the coder. I say reasonably, because if you allow SD unreasonable situations, everything is ambiguous: That's for me the reason that len(42) is ambiguous. The OP apparently had 1 as expectation, whereas my first thought was the minimal number of bits to represent the number and 7.5 million came later :=). The number of bits I certainly find reasonable, and I would find the number of decimal digits equally reasonable. More so than 1, actually. 1 as the length of an int doesn't give any information. Well, for my two cents, I will say that the number of binary bits or decimal digits is certainly the most sensible return value, and that the former is the most useful, because the latter can be got with len(str(42)). However, the former can also be (/slightly/ less)easily got with len(bin(42))-2... I also think that Explicit is better than implicit. says that there should be no return value in this case, as any return value would be implicit. Marcus -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Steven D'Aprano wrote: But it's not practically every function. It's hardly any function at all -- in my code, I don't think I've ever wanted this behavior. I would consider it an error for function(42) and function([42]) to behave the same way. One is a scalar, and the other is a vector -- they're different things, it's poor programming practice to treat them identically. (If Matlab does this, so much the worse for Matlab, in my opinion.) There's actually good reason to do this in heavily matrix-oriented specialized languages; there are numerous applications where scalars and 1x1 matrices are mathematically equivalent. -- Erik Max Francis m...@alcyone.com http://www.alcyone.com/max/ San Jose, CA, USA 37 18 N 121 57 W AIM/Y!M/Skype erikmaxfrancis Gods are born and die, but the atom endures. -- Alexander Chase -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sat, Jul 25, 2009 at 4:21 PM, Erik Max Francism...@alcyone.com wrote: Steven D'Aprano wrote: But it's not practically every function. It's hardly any function at all -- in my code, I don't think I've ever wanted this behavior. I would consider it an error for function(42) and function([42]) to behave the same way. One is a scalar, and the other is a vector -- they're different things, it's poor programming practice to treat them identically. (If Matlab does this, so much the worse for Matlab, in my opinion.) There's actually good reason to do this in heavily matrix-oriented specialized languages; there are numerous applications where scalars and 1x1 matrices are mathematically equivalent. The pertinent issue here being that Python, as a language, is neither matrix-oriented nor special-purpose. :) Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Chris Rebert wrote: On Sat, Jul 25, 2009 at 4:21 PM, Erik Max Francism...@alcyone.com wrote: Steven D'Aprano wrote: But it's not practically every function. It's hardly any function at all -- in my code, I don't think I've ever wanted this behavior. I would consider it an error for function(42) and function([42]) to behave the same way. One is a scalar, and the other is a vector -- they're different things, it's poor programming practice to treat them identically. (If Matlab does this, so much the worse for Matlab, in my opinion.) There's actually good reason to do this in heavily matrix-oriented specialized languages; there are numerous applications where scalars and 1x1 matrices are mathematically equivalent. The pertinent issue here being that Python, as a language, is neither matrix-oriented nor special-purpose. :) Yes. And I was responding to the comment that such a feature of a language would a priori be poor design. It _isn't_ poor design for special purpose languages. Python isn't one of them, but Matlab _is_. -- Erik Max Francis m...@alcyone.com http://www.alcyone.com/max/ San Jose, CA, USA 37 18 N 121 57 W AIM/Y!M/Skype erikmaxfrancis More fodder for the new lost generation -- Nik Kershaw -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Sat, Jul 25, 2009 at 6:47 PM, Erik Max Francism...@alcyone.com wrote: Chris Rebert wrote: On Sat, Jul 25, 2009 at 4:21 PM, Erik Max Francism...@alcyone.com wrote: Steven D'Aprano wrote: But it's not practically every function. It's hardly any function at all -- in my code, I don't think I've ever wanted this behavior. I would consider it an error for function(42) and function([42]) to behave the same way. One is a scalar, and the other is a vector -- they're different things, it's poor programming practice to treat them identically. (If Matlab does this, so much the worse for Matlab, in my opinion.) There's actually good reason to do this in heavily matrix-oriented specialized languages; there are numerous applications where scalars and 1x1 matrices are mathematically equivalent. The pertinent issue here being that Python, as a language, is neither matrix-oriented nor special-purpose. :) Yes. And I was responding to the comment that such a feature of a language would a priori be poor design. It _isn't_ poor design for special purpose languages. Python isn't one of them, but Matlab _is_. I was agreeing with your point actually. That was what I was trying to convey in my post. Apparently I wasn't as successful in that regard as I'd hoped. - Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. If len(7) returned a value of 1, then wouldn't one expect 7[0] to be valid? It isn't, so you'd then have to redefine all types so that they are sequences that can be indexed. Sounds like a big mess to me... [Are there types for which len() returns a value that can't be indexed?] -- Grant Edwards grante Yow! It's the RINSE CYCLE!! at They've ALL IGNORED the visi.comRINSE CYCLE!! -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, 24 Jul 2009 14:57:02 +0100, Grant Edwards inva...@invalid wrote: On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. If len(7) returned a value of 1, then wouldn't one expect 7[0] to be valid? It isn't, so you'd then have to redefine all types so that they are sequences that can be indexed. Sounds like a big mess to me... [Are there types for which len() returns a value that can't be indexed?] Dictionaries. Which doesn't make your point less valid. In fact I'd go so far as to argue that what len() gives you is the number of items in a container, so len(7) should return 0. -- Rhodri James *-* Wildebeest Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk wrote: Which doesn't make your point less valid. In fact I'd go so far as to argue that what len() gives you is the number of items in a container, so len(7) should return 0. Nah. 7 contains three bits, so len(7) should *clearly* return 3. Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Mark Dickinson wrote: On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk wrote: Which doesn't make your point less valid. In fact I'd go so far as to argue that what len() gives you is the number of items in a container, so len(7) should return 0. Nah. 7 contains three bits, so len(7) should *clearly* return 3. and len(7) must return 8, by the same token... but wait! len(7) 1 my python installation must me outdated ;-) bye -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Mark Dickinson schrieb: On Jul 24, 3:11 pm, Rhodri James rho...@wildebst.demon.co.uk wrote: Which doesn't make your point less valid. In fact I'd go so far as to argue that what len() gives you is the number of items in a container, so len(7) should return 0. Nah. 7 contains three bits, so len(7) should *clearly* return 3. But it contains a minimum of 32 bits! And why are you treating ones as special over zeros? I thought the times of BitRacism were finally over... Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Rhodri James rho...@wildebst.demon.co.uk (RJ) wrote: RJ On Fri, 24 Jul 2009 14:57:02 +0100, Grant Edwards inva...@invalid wrote: On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. If len(7) returned a value of 1, then wouldn't one expect 7[0] to be valid? It isn't, so you'd then have to redefine all types so that they are sequences that can be indexed. Sounds like a big mess to me... [Are there types for which len() returns a value that can't be indexed?] RJ Dictionaries. RJ Which doesn't make your point less valid. In fact I'd go so RJ far as to argue that what len() gives you is the number of RJ items in a container, so len(7) should return 0. But len(7) could as well be defined as 3, 1, 32, or 64 (depending on the implementation). Therefore it doesn't make much sense. -- Piet van Oostrum p...@cs.uu.nl URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4] Private email: p...@vanoostrum.org -- http://mail.python.org/mailman/listinfo/python-list
Re: Re: len() should always return something
I've read the "Zen of Python", but most of these aphorisms are vague and could be understood differently by different readers. In particular, I don't understand the statement that "explicit is better than implicit". Some examples of this would be helpful.I've been converting Matlab codes to Python. In Matlab, a scalar is just a one-by-one matrix and has a length of 1. This convention seems no less arbitrary to me than Python's convention that the concept of length is not applicable to ints and floats. My workaround was to write the following function:def is_scalar(x): """Return True if x is an instance of int, float, or complex. Otherwise, return False. Note: If x is a length-1 list or array containing an int, float, or complex value, False is returned.""" if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex): return True return FalseThe application is the following: In various types of scientific applications, one operates on a list of measurements. If there is only a single measurement, it is reasonable to allow the calling program to pass a scalar without wrapping it up into a list or array.PhillipJul 24, 2009 07:02:29 AM, c...@rebertia.com wrote:On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M.Feldmanpfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x): if isinstance(x,int) or isinstance(x,float): return 1 return len(x) But, this shouldn't be necessary.The problem is that redefining len()/length/size that way wouldviolate several principles of Python's design (The "Zen" of Python -http://www.python.org/dev/peps/pep-0020/).Specifically:- Explicit is better than implicit.- Special cases aren't special enough to break the rules.- Errors should never pass silently.- In the face of ambiguity, refuse the temptation to guess.If you'd explain the situation that prompts you to find thisredefinition necessary, I'm sure someone can suggest a betterapproach.Cheers,Chris-- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, 24 Jul 2009 16:10:07 +0100, Piet van Oostrum p...@cs.uu.nl wrote: Rhodri James rho...@wildebst.demon.co.uk (RJ) wrote: RJ On Fri, 24 Jul 2009 14:57:02 +0100, Grant Edwards inva...@invalid wrote: On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. If len(7) returned a value of 1, then wouldn't one expect 7[0] to be valid? It isn't, so you'd then have to redefine all types so that they are sequences that can be indexed. Sounds like a big mess to me... [Are there types for which len() returns a value that can't be indexed?] RJ Dictionaries. RJ Which doesn't make your point less valid. In fact I'd go so RJ far as to argue that what len() gives you is the number of RJ items in a container, so len(7) should return 0. But len(7) could as well be defined as 3, 1, 32, or 64 (depending on the implementation). Therefore it doesn't make much sense. Quite. -- Rhodri James *-* Wildebeest Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: Re: len() should always return something
Jul 24, 2009 07:02:29 AM, c...@rebertia.com wrote: On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M. Feldmanpfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x): if isinstance(x,int) or isinstance(x,float): return 1 return len(x) But, this shouldn't be necessary. The problem is that redefining len()/length/size that way would violate several principles of Python's design (The Zen of Python - http://www.python.org/dev/peps/pep-0020/). Specifically: - Explicit is better than implicit. - Special cases aren't special enough to break the rules. - Errors should never pass silently. - In the face of ambiguity, refuse the temptation to guess. If you'd explain the situation that prompts you to find this redefinition necessary, I'm sure someone can suggest a better approach. On Fri, Jul 24, 2009 at 8:58 AM, Phillip M. Feldmanpfeld...@verizon.net wrote: I've read the Zen of Python, but most of these aphorisms are vague and could be understood differently by different readers. In particular, I don't understand the statement that explicit is better than implicit. Some examples of this would be helpful. I've been converting Matlab codes to Python. In Matlab, a scalar is just a one-by-one matrix and has a length of 1. This convention seems no less arbitrary to me than Python's convention that the concept of length is not applicable to ints and floats. My workaround was to write the following function: def is_scalar(x): Return True if x is an instance of int, float, or complex. Otherwise, return False. Note: If x is a length-1 list or array containing an int, float, or complex value, False is returned. if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex): return True return False The application is the following: In various types of scientific applications, one operates on a list of measurements. If there is only a single measurement, it is reasonable to allow the calling program to pass a scalar without wrapping it up into a list or array. You could use Python's extended call syntax when defining your function: def average(*args): return sum(args) / len(args) average(7) #== 7 average(2,3,4,5,6) #== 4 average(*[2,3,4,5,6]) #== 4 average([2,3,4,5,6]) #== error Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Phillip M. Feldman wrote: I've been converting Matlab codes to Python. In Matlab, a scalar is just a one-by-one matrix and has a length of 1. This convention seems no less arbitrary to me than Python's convention that the concept of length is not applicable to ints and floats. Multiplication of a vector/matrix by a scalar always defined and commutative. Multiplication of a vector/matrix by a 1x1 matrix is not always even defined. So not having scalars in a matrix package strikes me as a bit odd. My workaround was to write the following function: def is_scalar(x): Return True if x is an instance of int, float, or complex. Otherwise, return False. Note: If x is a length-1 list or array containing an int, float, or complex value, False is returned. if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex): Better:if isinstance(x, (int, float, complex)): but you forgot decimals and fractions and any other possible number modules. In 3.1, from numbers import Number from decimal import Decimal from fractions import Fraction for x in 1, 1.0, (1+0j), Decimal(1), Fraction(1,1): isinstance(x, Number) True True True True True and the same for any other module that registers a class as a Number return True return False The application is the following: In various types of scientific applications, one operates on a list of measurements. If there is only a single measurement, it is reasonable to allow the calling program to pass a scalar without wrapping it up into a list or array. If you want to do that, start with def f(x): try: len(x) except TypeError: x = x, or in 3.1 use Number test above. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote: Nah. 7 contains three bits, so len(7) should *clearly* return 3. and len(7) must return 8, by the same token... but wait! len(7) 1 my python installation must me outdated ;-) No no no, you're obviously using an awesome version of Python that can compress single-character strings to a single bit! -- Steven -- http://mail.python.org/mailman/listinfo/python-list
list vs. tuple [Re: len() should always return something]
In article mailman.3674.1248461573.8015.python-l...@python.org, Terry Reedy tjre...@udel.edu wrote: Better:if isinstance(x, (int, float, complex)): I never noticed this before, but it seems odd that the second argument to isinstance() should be a tuple. Using the normal arguments made about tuples vs. lists, it seems like a list would be the right data structure here. I suppose a set would be even more right, but (I'm pretty sure) isinstance() predates sets. I'm curious why a tuple was chosen. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
In article 0279f596$0$5185$c3e8...@news.astraweb.com, Steven D'Aprano st...@remove-this-cybersource.com.au wrote: On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote: Nah. 7 contains three bits, so len(7) should *clearly* return 3. and len(7) must return 8, by the same token... but wait! len(7) 1 my python installation must me outdated ;-) No no no, you're obviously using an awesome version of Python that can compress single-character strings to a single bit! Compressing strings to a single bit is easy. It's the uncompressing that's tricky. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, 24 Jul 2009 00:02:28 -0700, Chris Rebert wrote: On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M. Feldmanpfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x): if isinstance(x,int) or isinstance(x,float): return 1 return len(x) But, this shouldn't be necessary. The problem is that redefining len()/length/size that way would violate several principles of Python's design (The Zen of Python - http://www.python.org/dev/peps/pep-0020/). Specifically: - Explicit is better than implicit. - Special cases aren't special enough to break the rules. - Errors should never pass silently. - In the face of ambiguity, refuse the temptation to guess. Chris, I'm curious why you think that these Zen are relevant to the OP's complaint. Re explicit vs implicit, len(42) is just as explicit as len([42, 23]). Arguably (I wouldn't argue this, but some people might) ints aren't special enough to break the rule that len(obj) should always return something. (I don't actually agree, but some people might be able to produce a coherent argument why len() should apply equally to all objects.) Re errors passing silently, the OP doesn't believe that len(42) should be an error, so that's not relevant. And there's nothing ambiguous about len(42). I agree with the current Python behaviour, but I don't think there's anything in the Zen to support it. As far as I know, there is no programming language which treats scalars like ints as if they were vectors of length 1, which makes Python's choice to make ints unlengthed a no-brainer. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: list vs. tuple [Re: len() should always return something]
On Fri, 24 Jul 2009 15:03:29 -0400, Roy Smith wrote: In article mailman.3674.1248461573.8015.python-l...@python.org, Terry Reedy tjre...@udel.edu wrote: Better:if isinstance(x, (int, float, complex)): I never noticed this before, but it seems odd that the second argument to isinstance() should be a tuple. Using the normal arguments made about tuples vs. lists, it seems like a list would be the right data structure here. What would be the point of using a list? You're never going to sort it, or append items to it, or otherwise mutate it. You build it, pass it to a function which doesn't modify it in any fashion, then it gets garbage collected. I suppose a set would be even more right, but (I'm pretty sure) isinstance() predates sets. Yes. [st...@sylar ~]$ python1.5 Python 1.5.2 (#1, Apr 1 2009, 22:55:54) [GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam isinstance built-in function isinstance set Traceback (innermost last): File stdin, line 1, in ? NameError: set I'm curious why a tuple was chosen. Tuples are smaller and faster to build than lists -- they're the most lightweight sequence type in Python. You don't need all the extra functionality of lists, so why go to the time and effort of building a list? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, Jul 24, 2009 at 12:05 PM, Steven D'Apranost...@remove-this-cybersource.com.au wrote: On Fri, 24 Jul 2009 00:02:28 -0700, Chris Rebert wrote: On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M. Feldmanpfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x): if isinstance(x,int) or isinstance(x,float): return 1 return len(x) But, this shouldn't be necessary. The problem is that redefining len()/length/size that way would violate several principles of Python's design (The Zen of Python - http://www.python.org/dev/peps/pep-0020/). Specifically: - Explicit is better than implicit. - Special cases aren't special enough to break the rules. - Errors should never pass silently. - In the face of ambiguity, refuse the temptation to guess. Chris, I'm curious why you think that these Zen are relevant to the OP's complaint. To explain in more detail: Re explicit vs implicit, len(42) is just as explicit as len([42, 23]). If you want a collection (something that has length), then one should explicitly create one, not implicitly have a singleton value act like it's a pseudo-collection. I admit I'm somewhat conflating this principle with the anti-ambiguity principle, but the two are related, imho. Arguably (I wouldn't argue this, but some people might) ints aren't special enough to break the rule that len(obj) should always return something. Except that's not the current rule. The current rule is that it's defined only for collections. One would instead have to argue why ints are special enough to have len() defined despite not being collections. I think the point made by Grant Edwards is instructive. len(x) = 1 typically implies list(x)[0] and similar should be valid. Altering the behavior would invalidate that theorem and cause quite a bit of code upheaval, all just to save the OP from typing one pair of []s. (I don't actually agree, but some people might be able to produce a coherent argument why len() should apply equally to all objects.) Well, yes, this /whole/ argument is entirely academic; the behavior is extremely unlikely to change, we're just trying to give ex post facto rationales for pedagogical purposes. :) Re errors passing silently, the OP doesn't believe that len(42) should be an error, so that's not relevant. True, it would not directly silence an error, but defining len() on scalars would tend towards obscuring errors in code that incorrectly treats scalars as collections. And there's nothing ambiguous about len(42). Really? What is its value then? I think arguments of varying quality can be made for: 1 - as the OP and those from array programming languages would suggest 2 - the number of decimal digits in 42, if one was feeling Perlish 6 - the minimum number of bits necessary to represent 42 in binary 32 (or 64, depending on your CPU) - the number of bits necessary to represent an int (obviously breaks down a bit with arbitrary-magnitude ints) undefined - i.e. it causes an error, the current behavior; asking for the length of a non-collection is nonsensical or absurd I agree with the current Python behaviour, but I don't think there's anything in the Zen to support it. As far as I know, there is no The problem and strength of the Zen is that it's all about how you interpret it. :-) Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On 7/24/2009 3:04 PM, Roy Smith wrote: In article 0279f596$0$5185$c3e8...@news.astraweb.com, Steven D'Aprano st...@remove-this-cybersource.com.au wrote: On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote: Nah. 7 contains three bits, so len(7) should *clearly* return 3. and len(7) must return 8, by the same token... but wait! len(7) 1 my python installation must me outdated ;-) No no no, you're obviously using an awesome version of Python that can compress single-character strings to a single bit! Compressing strings to a single bit is easy. It's the uncompressing that's tricky. I assume you mean ord(7)%2? First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p Marcus -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Marcus Wanner wrote: On 7/24/2009 3:04 PM, Roy Smith wrote: In article 0279f596$0$5185$c3e8...@news.astraweb.com, Steven D'Aprano st...@remove-this-cybersource.com.au wrote: On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote: Nah. 7 contains three bits, so len(7) should *clearly* return 3. and len(7) must return 8, by the same token... but wait! len(7) 1 my python installation must me outdated ;-) No no no, you're obviously using an awesome version of Python that can compress single-character strings to a single bit! Compressing strings to a single bit is easy. It's the uncompressing that's tricky. I assume you mean ord(7)%2? First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p Marcus asciichar = chr(len(0)) if the OP's wishes come true? -- Kindest regards. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On 7/24/2009 4:18 PM, Mark Lawrence wrote: Marcus Wanner wrote: On 7/24/2009 3:04 PM, Roy Smith wrote: In article 0279f596$0$5185$c3e8...@news.astraweb.com, Steven D'Aprano st...@remove-this-cybersource.com.au wrote: On Fri, 24 Jul 2009 16:50:03 +0200, superpollo wrote: Nah. 7 contains three bits, so len(7) should *clearly* return 3. and len(7) must return 8, by the same token... but wait! len(7) 1 my python installation must me outdated ;-) No no no, you're obviously using an awesome version of Python that can compress single-character strings to a single bit! Compressing strings to a single bit is easy. It's the uncompressing that's tricky. I assume you mean ord(7)%2? First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p Marcus asciichar = chr(len(0)) if the OP's wishes come true? Nope, wasn't ?... Marcus -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Marcus Wanner wrote: First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p Bah...uncompressing the value 0 into *an* ASCII character is easy. Uncompressing it into the *original* ASCII character from which it was compressed (with the aforementioned compression method) becomes a bit trickier ;-) -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, Jul 24, 2009 at 1:30 PM, Tim Chasepython.l...@tim.thechases.com wrote: Marcus Wanner wrote: First one to correctly decompress the value 0 into an ASCII character wins the title of the world's most capable hacker :p Bah...uncompressing the value 0 into *an* ASCII character is easy. Uncompressing it into the *original* ASCII character from which it was compressed (with the aforementioned compression method) becomes a bit trickier ;-) Deja vu: http://www.hackles.org/cgi-bin/archives.pl?request=310 - Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: list vs. tuple [Re: len() should always return something]
Steven D'Aprano wrote: On Fri, 24 Jul 2009 15:03:29 -0400, Roy Smith wrote: In article mailman.3674.1248461573.8015.python-l...@python.org, Terry Reedy tjre...@udel.edu wrote: Better:if isinstance(x, (int, float, complex)): I never noticed this before, but it seems odd that the second argument to isinstance() should be a tuple. Using the normal arguments made about tuples vs. lists, it seems like a list would be the right data structure here. I ignore the 'normal arguments' and it seems that Guido or the designer of isinstance did so here too. Fortunately. Practicality beats 'purity', especially misguided purity. What would be the point of using a list? You're never going to sort it, or append items to it, or otherwise mutate it. You build it, pass it to a function which doesn't modify it in any fashion, then it gets garbage collected. I suppose a set would be even more right, but (I'm pretty sure) isinstance() predates sets. Yes. [st...@sylar ~]$ python1.5 Python 1.5.2 (#1, Apr 1 2009, 22:55:54) [GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam isinstance built-in function isinstance set Traceback (innermost last): File stdin, line 1, in ? NameError: set I'm curious why a tuple was chosen. Tuples are smaller and faster to build than lists -- they're the most lightweight sequence type in Python. You don't need all the extra functionality of lists, so why go to the time and effort of building a list? In fact, constant tuples can be and now are compiled as constants: dis(compile('(1,2,3)','','eval')) 1 0 LOAD_CONST 3 ((1, 2, 3)) 3 RETURN_VALUE dis(compile('[1,2,3]','','eval')) 1 0 LOAD_CONST 0 (1) 3 LOAD_CONST 1 (2) 6 LOAD_CONST 2 (3) 9 BUILD_LIST 3 12 RETURN_VALUE Internally, even a frozenset is more complicated than a tuple since it still needs a hash table, which is overkill for something that will be linearly scanned exactly once. tjr -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Chris Rebert wrote: I think the point made by Grant Edwards is instructive. len(x) = 1 typically implies list(x)[0] and similar should be valid. At least, one should be able to iterate with x and get len(x) items. See below. And there's nothing ambiguous about len(42). Really? What is its value then? I think arguments of varying quality can be made for: 1 - as the OP and those from array programming languages would suggest 2 - the number of decimal digits in 42, if one was feeling Perlish 6 - the minimum number of bits necessary to represent 42 in binary 32 (or 64, depending on your CPU) - the number of bits necessary to represent an int (obviously breaks down a bit with arbitrary-magnitude ints) undefined - i.e. it causes an error, the current behavior; asking for the length of a non-collection is nonsensical or absurd In set theory, one can define counts recursively as follows 0 = {} (set, not dict) n+1 = n | {n} so len(n) = n, and in particular, len(42) = 42. On the same basis, it has been proposed (and rejected) that iter(n) == range(n), do that we could write 'for i in 10' for instance. Guido thought this too esoteric. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: list vs. tuple [Re: len() should always return something]
Roy Smith r...@panix.com wrote: In article mailman.3674.1248461573.8015.python-l...@python.org, Terry Reedy tjre...@udel.edu wrote: Better:if isinstance(x, (int, float, complex)): I never noticed this before, but it seems odd that the second argument to isinstance() should be a tuple. Using the normal arguments made about tuples vs. lists, it seems like a list would be the right data structure here. I suppose a set would be even more right, but (I'm pretty sure) isinstance() predates sets. I'm curious why a tuple was chosen. There's a very good reason[*]. The second argument to isinstance() is a classinfo where a classinfo is a type or a tuple of classinfo. That means you can have an arbitrarily complex set of nested tuples e.g. (int, (float, complex)), but the immutable nature of tuples means the implementation of isinstance can walk the tuple tree without ever having to worry about infinite loops. If classinfo could be a list of types then someone somewhere would feed it a recursive list and then complain that the interpreter crashed. Exception specifications are tuples for the same reason. [*] For some definition of 'very good'. Would Python be significantly impaired if you couldn't combine classinfos into a tree structure? Probably not. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Dr. Phillip M. Feldman pfeld...@verizon.net wrote in message news:mailman.3644.1248417347.8015.python-l...@python.org... Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. So you want len() to treat 123 as though it could potentially be a list containing a single element? In that case there could be an ambiguity here: print len([10,20,30]) Should it print 3 (the elements in [10,20,30]), or 1 (treating [10,20,30] as a potential list containing the single element [10,20,30])? -- bartc -- http://mail.python.org/mailman/listinfo/python-list
Re: list vs. tuple [Re: len() should always return something]
isinstance(x, (int, float, complex)) is certainly very compact, and does what I want. Thanks! -- View this message in context: http://www.nabble.com/len%28%29-should-always-return-something-tp24639361p24654347.html Sent from the Python - python-list mailing list archive at Nabble.com. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
As far as I know, there is no programming language which treats scalars like ints as if they were vectors of length 1 Actually, Matlab does: length(5) ans = 1 -- View this message in context: http://www.nabble.com/len%28%29-should-always-return-something-tp24639361p24654358.html Sent from the Python - python-list mailing list archive at Nabble.com. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. Phillip Diez B. Roggisch-2 wrote: Dr. Phillip M. Feldman schrieb: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. Of course, I can define my own function like this: def mylen(x): if isinstance(x,int) or isinstance(x,float): return 1 return len(x) But, this shouldn't be necessary. Can you show some example of where that is actually making a piece of code more elegant? Diez -- http://mail.python.org/mailman/listinfo/python-list -- View this message in context: http://www.nabble.com/len%28%29-should-always-return-something-tp24639361p24654439.html Sent from the Python - python-list mailing list archive at Nabble.com. -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Fri, Jul 24, 2009 at 7:50 PM, Dr. Phillip M. Feldmanpfeld...@verizon.net wrote: Here's a simple-minded example: def dumbfunc(xs): for x in xs: print x This function works fine if xs is a list of floats, but not if it is single float. It can be made to work as follows: def dumbfunc(xs): if isinstance(xs,(int,float,complex)): xs= [xs] for x in xs: print x Having to put such extra logic into practically every function is one of the annoying things about Python. You can easily fix that using decorators: (disclaimer: untested, except mentally) #bit of setup; pays off later def list_or_single(func): def wrapper(arg): try: iter(arg) except TypeError: arg = [arg] return func(arg) return wrapper #now just prefix functions with @list_or_single @list_or_single def dumbfunc(xs): for x in xs: print x Using the extended call syntax as I explained earlier is another option. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: len() should always return something
On Jul 24, 6:57 am, Grant Edwards inva...@invalid wrote: On 2009-07-24, Dr. Phillip M. Feldman pfeld...@verizon.net wrote: Some aspects of the Python design are remarkably clever, while others leave me perplexed. Here's an example of the latter: Why does len() give an error when applied to an int or float? len() should always return something; in particular, when applied to a scalar, it should return a value of 1. If len(7) returned a value of 1, then wouldn't one expect 7[0] to be valid? It isn't, so you'd then have to redefine all types so that they are sequences that can be indexed. Sounds like a big mess to me... You can call the big mess Matlab. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list