Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap syntax does not work #255

Closed
jmoraleda opened this issue Sep 22, 2022 · 4 comments
Closed

Swap syntax does not work #255

jmoraleda opened this issue Sep 22, 2022 · 4 comments

Comments

@jmoraleda
Copy link
Contributor

In a regular dict, e.g. w = {1:1, 2:2} one can swap the values of two keys with w[1],w[2] = w[2],w[1] but this does not work if w is a bidict giving the error KeyAndValueDuplicationError: (1, 2).

If this behavior can be fixed (which I doubt) it should, but otherwise perhaps is could be documented as a limitation and a difference with a regular dict.

By the way, as a work around (in case others arrive here with the same problem), one can simply pop the offending element before the swap as follows:

val2 = w.pop(2)
w[1],w[2] = val2, w[1]
@jab
Copy link
Owner

jab commented Sep 24, 2022

You're right to doubt that this behavior can be "fixed". The current behavior is actually consistent with the relevant section of the https://docs.python.org/3/reference/simple_stmts.html docs:

Although the definition of assignment implies that overlaps between the left-hand side and the right-hand side are ‘simultaneous’ (for example a, b = b, a swaps two variables), overlaps within the collection of assigned-to variables occur left-to-right, sometimes resulting in confusion. For instance, the following program prints [0, 2]:

x = [0, 1]
i = 0
i, x[i] = 1, 2         # i is updated, then x[i] is updated
print(x)

So with b = bidict({1:1, 2:2}), b[1], b[2] = b[2], b[1] is by definition equivalent to

b[1] = b[2]
b[2] = b[1]

which correctly raises KeyAndValueDuplicationError on the first assignment (before it even gets to the second).

Would you like to submit a PR to the https://bidict.readthedocs.io/en/main/addendum.html#caveats docs? I think that's a good suggestion. Thanks!

@jmoraleda
Copy link
Contributor Author

jmoraleda commented Sep 24, 2022

Thank you for your fast meaningful reply, and for your work in bidict.

To be precise, the statement b[1], b[2] = b[2], b[1] is by definition equivalent to

_temporary_internal_tuple = b[2], b[1]
b[1] = _temporary_internal_tuple[0]
b[2] = _temporary_internal_tuple[1]

rather than

b[1] = b[2]
b[2] = b[1]

The distinction is important because when using a regular python dict b[1], b[2] = b[2], b[1] results in b being equal to {1:2, 2:1} while

b[1] = b[2]
b[2] = b[1]

results in b being equal to {1:2, 2:2}.

A casual user might expect the swap to work for bidict just as it does in a regular dict so to document this difference between dict and bidict I propose writing a new section at the end of Addendum -> Caveats with the following content:


Simultanous Assignment

bidict behaves differently than dict with respect to simultaneous assignment. For example, for a regular dict e.g. b = {1:1, 2:2} we can swap two values with b[1], b[2] = b[2], b[1]. which results inb being equal to {1:2, 2:1} but if b = bidict({1:1, 2:2}) then b[1], b[2] = b[2], b[1] results in a KeyAndValueDuplicationError: (1, 2) and to swap the values one must run:

val2 = b.pop(2)
b[1],b[2] = val2, b[1]

This limitation is a direct consequence of the fact that the statement b[1], b[2] = b[2], b[1] is by definition equivalent to

_temporary_internal_tuple = b[2], b[1]
b[1] = _temporary_internal_tuple[0]
b[2] = _temporary_internal_tuple[1]

as described in https://docs.python.org/3/reference/simple_stmts.html docs:


If you agree I can submit a PR for it. Thank you again.

@jab
Copy link
Owner

jab commented Sep 25, 2022 via email

@jab
Copy link
Owner

jab commented Sep 28, 2022

@jab jab closed this as completed Sep 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants