is there any implementation of python2 where ordering is transitive?

  • Last Update :
  • Techknowledgy :

CPython (and variants), PyPy, and Jython:

>>> 'b' < () < u 'ab' < 'b'
True

IronPython internally compares the .NET Object.GetHashCode() hashes of unlike objects, so you can break it by abusing the special handling of int and float comparisons and the fact that the internal hash representation of float('+inf') is less than the hash of [] (I'm not sure how stable this is, so it might not work on every installation of IronPython):

>>> 2 ** 200 < float('+inf') < [] < 2 ** 200
True
>>> {
   1: 3
} < {
   1: 4
} < {
   1: 3
}
1
   >>>
   {
      1: 3
   } < {
      1: 3
   }
0

For CPython 2, you would actually have [t]uple < [u]nicode, but because unicode and str comparisons are handled as a special case, you lose transitivity. Although it's unlikely that Python 2 will get a patch to fix this "bug", I think you can ensure transitivity by just explicitly changing the order from:

[d] ict < [l] ist < [s] tring < [t] uple < [u] nicode

To:

[u] nicode < [d] ict < [l] ist < [s] tring < [t] uple

Example: broken transitivity in IronPython (inspired by Blender's comment and simplified):

>>> assert long(0) < 1.0 < [] < long(0) # 0 < 1;
'float' < 'list' < 'long'

Examples use many trivial user-defined classes, with names one-letter capital or lowercase:

class A(object): pass

class a(object): pass
   ...

   class z(object): pass

All numeric types have many naturally equivalent values in CPython and IronPython (and probably in all other implementations according docs)

>>> assert(False == 0 == 0 L == 0.0 == 0 + 0 j == Decimal('0') == Fraction(0, 1) <
   ...True == 1 == 1 L == 1.0 == 1 + 0 j == Decimal('1') == Fraction(1, 1))

Numeric types are dispersed between other types in IronPython

>>> assert D() < decimal.Decimal('0') < E() >>>
   assert F() < fractions.Fraction(0, 1) < G() >>>
   assert b() < False < c() # bool >>>
   assert c() < 0 + 0 j < d() # complex >>>
   assert f() < 0.0 < g() # float >>>
   assert i() < 0 < j() # int >>>
   assert l() < 0 L < m() # long

str, bytearray and unicode have equivalent values

>>> assert bytearray('ab') == 'ab' == u 'ab'

Suggestion : 2

Last Updated : 16 Jun, 2022

The original dictionary: {
   3: 5,
   4: 'd',
   7: 'k',
   'b': 4,
   'l': 7,
   'a': 3
}
The resolved dictionary: {
   'b': 'd',
   'l': 'k',
   'a': 5
}

Suggestion : 3

Except when part of a list or set display, an expression list containing at least one comma yields a tuple. The length of the tuple is the number of expressions in the list. The expressions are evaluated from left to right.,A list display yields a new list object, the contents being specified by either a list of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and placed into the list object in that order. When a comprehension is supplied, the list is constructed from the elements resulting from the comprehension.,A set display yields a new mutable set object, the contents being specified by either a sequence of expressions or a comprehension. When a comma-separated list of expressions is supplied, its elements are evaluated from left to right and added to the set object. When a comprehension is supplied, the set is constructed from the elements resulting from the comprehension.,To avoid interfering with the expected operation of the generator expression itself, yield and yield from expressions are prohibited in the implicitly defined generator.

Python supports string and bytes literals and various numeric literals:

literal:: = stringliteral | bytesliteral |
   integer | floatnumber | imagnumber

A parenthesized form is an optional expression list enclosed in parentheses:

parenth_form:: = "(" [starred_expression]
")"

Common syntax elements for comprehensions are:

comprehension:: = assignment_expression comp_for
comp_for:: = ["async"]
"for"
target_list "in"
or_test[comp_iter]
comp_iter:: = comp_for | comp_if
comp_if:: = "if"
or_test[comp_iter]

A list display is a possibly empty series of expressions enclosed in square brackets:

list_display:: = "[" [starred_list | comprehension]
"]"

A set display is denoted by curly braces and distinguishable from dictionary displays by the lack of colons separating keys and values:

set_display:: = "{"(starred_list | comprehension)
"}"

A dictionary display is a possibly empty series of key/datum pairs enclosed in curly braces:

dict_display:: = "{" [key_datum_list | dict_comprehension]
"}"
key_datum_list:: = key_datum(","
   key_datum) * [","]
key_datum:: = expression ":"
expression | "**"
or_expr
dict_comprehension:: = expression ":"
expression comp_for