On Sat, 08 Nov 2008 20:36:59 0800, Kay Schluehr wrote:
> On 9 Nov., 05:04, Terry Reedy <(EMail Removed)> wrote:
>
>> Have you written any Python code where you really wanted the old,
>> unpredictable behavior?
>
> Sure:
>
> if len(L1) == len(L2):
> return sorted(L1) == sorted(L2) # check whether two lists contain
> the same elements
> else:
> return False
>
> It doesn't really matter here what the result of the sorts actually is
> as long as the algorithm leads to the same result for all permutations
> on L1 ( and L2 ).
How often do you care about equality ignoring order for lists containing
arbitrary, heterogeneous types?
In any case, the above doesn't work now, since either L1 or L2 might
contain complex numbers. The sorted() trick only works because you're
making an assumption about the kinds of things in the lists. If you want
to be completely general, the above solution isn't guaranteed to work.
If you're prepared to assume hashability, then the obvious Multiset
solution is probably better even than the above. If you want complete
generality, you can't even assume that items in the list can be ordered
at all, so you need something like this:
def collate_and_sort(L):
D = {}
for item in L:
t = type(item)
x = D.setdefault(t, [])
x.append(item)
for x in D.values():
try:
x.sort()
except TypeError:
try:
x.sort(key=str)
except TypeError:
x.sort(key=id)
return D
def unordered_equals(L1, L2):
if len(L1) != len(L2):
return False
try:
return sorted(L1) == sorted(L2)
except TypeError:
return collate_and_sort(L1) == collate_and_sort(L2)
But note that even this solution isn't perfect, since it will fail to do
the right thing for L1=[1, {}, 2] and L2=[1, {}, 2.0]. Here is a way to
solve the problem assuming only that the items support equality:
def unordered_equals2(L1, L2):
if len(L1) != len(L2):
return False
for item in L1:
if L1.count(item) != L2.count(item):
return False
return True

Steven
