On Fri, Aug 26, 2016 at 6:50 PM, d...@forestfield.co.uk <d...@forestfield.co.uk> wrote: > In a program I'm converting to Python 3 I'm examining a list of divisor > values, some of which can be None, to find the first with a value greater > than 1. > > Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on > win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> None > 1 > False > > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit > (AMD64)] on win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> None > 1 > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: unorderable types: NoneType() > int() > > I can live with that but I'm curious why it was decided that this should now > raise an error.
Because it doesn't make sense to compare these things in this way. You can compare some things (eg integers and floats), but others don't usefully arrange themselves into any sort of order. It tends to lead to odd situations: rosuav@sikorsky:~$ python2 Python 2.7.12+ (default, Aug 4 2016, 20:04:34) [GCC 6.1.1 20160724] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 10 < "15" True >>> "15" < 20 False >>> "asdf" < (1,2,3) True >>> "asdf" > [1,2,3] True >>> rosuav@sikorsky:~$ python3 Python 3.6.0a4+ (default:4b64a049f451+, Aug 19 2016, 23:41:43) [GCC 6.1.1 20160802] on linux Type "help", "copyright", "credits" or "license" for more information. >>> 10 < "15" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'int' and 'str' >>> With Py3, it's simple and obvious: comparing integers and strings is an error. With Py2, there's the extremely odd rule that all integers are lower than all lists are lower than all strings are lower than all tuples - it's based on the name of the type. (Except for 'long', which appears to sort as though it were called 'int'. I think.) The Py2 behaviour allows you to get a consistent-but-meaningless sort order among disparate types, but it's a bug magnet, and it goes against Python's philosophy of telling you about problems right away. Py3 fixed quite a number of those kinds of issues (eg you can't combine byte strings and Unicode strings in Py3, yet you can in Py2), with the result that a number of data-dependent bugs in Py2 become instant exceptions in Py3. The simplest way to fix your code here is to explicitly provide a default. For instance: divisors = [None, 1, None, 2, 7, None, 1] greater_than_one = (div for div in divisors if (div or 0) > 1) The (div or 0) part means that any None will be treated as zero. (Also, zero will be treated as zero - be careful of this if you change the default, eg to 1.) At that point, all your comparisons will involve numbers, which have well-defined inequality comparisons. ChrisA -- https://mail.python.org/mailman/listinfo/python-list