how to test for atomicity/mutability/hashability?

K

kj

I want to implement a test t() that will return True if its two
arguments are "completely" different. By this I mean that they
don't share any "non-atomic" component. E.g., if

a = [0, 1]
b = [0, 1]
c = [2, 3]
d = [2, 3]

A = (a, c, 0)
B = (a, d, 1)
C = (b, d, 0)

The desired test t() would yield:

t(A, B) -> False (A and B share the mutable component a)
t(A, C) -> True (a =!= c, b =!= d, and 0 is not mutable)
t(B, C) -> False (B and C share the mutable component d)

(=!= is shorthand with "is not identical to".)

It would facilitate the implementation of t() to have a simple test
for mutability. Is there one?

Thanks!

~kj
 
C

Chris Rebert

It would facilitate the implementation of t() to have a simple test
for mutability.  Is there one?

Non-default hashability is an approximate heuristic:

def is_immutable(x):
try:
hash(x)
except TypeError:
return False
else:
klass = type(x)
return klass is object or klass.__hash__ is not object.__hash__

Cheers,
Chris
 
A

Arnaud Delobelle

kj said:
I want to implement a test t() that will return True if its two
arguments are "completely" different. By this I mean that they
don't share any "non-atomic" component. E.g., if

a = [0, 1]
b = [0, 1]
c = [2, 3]
d = [2, 3]

A = (a, c, 0)
B = (a, d, 1)
C = (b, d, 0)

The desired test t() would yield:

t(A, B) -> False (A and B share the mutable component a)
t(A, C) -> True (a =!= c, b =!= d, and 0 is not mutable)
t(B, C) -> False (B and C share the mutable component d)

(=!= is shorthand with "is not identical to".)

It would facilitate the implementation of t() to have a simple test
for mutability. Is there one?

Thanks!

~kj

I think defining mutability is subject to opinion, but here is a first
approximation.


def mutable(obj):
return obj.__hash__ is None or type(obj).__hash__ == object.__hash__

def t(l1, l2):
return not any(mutable(x) and x is y for x, y in zip(l1, l2))

a = [0, 1]
b = [0, 1]
c = [2, 3]
d = [2, 3]

A = (a, c, 0)
B = (a, d, 1)
C = (b, d, 0)

False
 
C

Chris Rebert

kj said:
I want to implement a test t() that will return True if its two
arguments are "completely" different.  By this I mean that they
don't share any "non-atomic" component.  E.g., if

a = [0, 1]
b = [0, 1]
c = [2, 3]
d = [2, 3]

A = (a, c, 0)
B = (a, d, 1)
C = (b, d, 0)

The desired test t() would yield:

t(A, B) -> False (A and B share the mutable component a)
t(A, C) -> True (a =!= c, b =!= d, and 0 is not mutable)
t(B, C) -> False (B and C share the mutable component d)

(=!= is shorthand with "is not identical to".)

It would facilitate the implementation of t() to have a simple test
for mutability.  Is there one?

Thanks!

~kj

I think defining mutability is subject to opinion, but here is a first
approximation.


def mutable(obj):
   return obj.__hash__ is None or type(obj).__hash__ == object.__hash__

Corner case (I think):Traceback (most recent call last):
True

Cheers,
Chris
 
A

Arnaud Delobelle

Chris Rebert said:
Corner case (I think):
Traceback (most recent call last):

True

Ah true. There was also the problem that e.g. mutable(tuple) was False.

How about this second approximation:

def mutable(obj):
h = type(obj).__hash__
return not h or h is object.__hash__ and type(obj) is not object
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top