python bijection

Joshua Bronson jabronson at gmail.com
Tue Dec 1 16:19:22 EST 2009


On Dec 1, 2:11 pm, Raymond Hettinger <python at rcn.com> wrote:
> [Joshua Bronson]
>
> > Raymond, do you think there might be any future in including a built-
> > in bidict data structure in Python?
>
> I don't think so.  There are several forces working against it:
>
> * the recipe is new, so it hasn't had a chance to mature
>   or to gain a fan club.
>
> * there are many approaches to the solving the problem and
>   there is no reason to assume this one is the best.
>
> * it extends the language with arcane syntax tricks instead of
>   using the language as designed by Guido.  That makes it harder
>   to learn and remember.
>
> * we've already got one (actually two).  The two dictionary approach
>   uses plain python, requires no new learning, and is more flexible.
>   Also, sqlite3 provides another way to use multiple lookups to a
>   single record.  The database approach is much more general
>   (extending to trijections, allowing multiple sort orders,
>   providing persistence, etc).

all good points.

> * the semantics of a bijection aren't obvious:
>
>      b['x'] = 'ex'      # first record:  ('x', 'ex')
>      b['y'] = 'why'     # second record: ('y', 'why')
>      b[:'why'] = 'x'    # do two records collapse into one? is there
> an error?

In my implementation the two records collapse into one, on the theory
that if you say it you mean it, but you're right that the semantics
aren't obvious, especially since in sql this would be an error. Thank
you for pointing this out, it totally slipped my mind to document it!
(Noted now.) If my bidict package ever has >1 user, and they prefer
this to be an error, I'd totally change it.

> * the proposed syntax doesn't address the issue covered in my previous
> post.
>   Since bijections are symmetrical, they do not have an obvious
> direction
>   (which is the primary key, the husband or the wife?).  The syntax
> needs to
>   allow user names to make it clear which is being accessed:
>
>      marriages.h2w['john'] = 'amy'
>      marriages.w2h['amy'] = 'john'
>
>   Contrast this with:
>
>      marriages['jordan'] = 'taylor'    # are you sure you got the
> order correct?
>      marriages[:'taylor'] = 'jordan'   # this is easy to get backwards

The "namedbidict" class factory I wrote on your recommendation allows
for the former. But it's still up to the user to choose names which
indicate the direction of the mapping, whether she uses namedbidict or
not:

    marriages.husbands['john'] = 'amy'  # namedbidict, direction
unclear
    h2w['john'] = 'amy'  # regular bidict, but not unclear b/c name is
'h2w'


(you can use

    >>> marriages.inv is marriages.husbands
    False

to tell that husbands is the forward mapping, but that sucks -- better
to have called it h2w or some such in the first place.)


Thanks for the thoughtful reply.

Josh



More information about the Python-list mailing list