5 ms·
Why dont all languages have the inplace swap built in like python has? In python you can just do: y, x = x, y
by tweakimp 4y ago
Why dont all languages have the inplace swap built in like python has?
In python you can just do: y, x = x, y
- xxs 4y agoIt only makes sense to swap elements of an arrays (lists). Swapping variable is super rare. I can't recall the same time I had to swap two integers/floats or even object references.
- eesmith 4y agoYou're right! I was surprised. I did: ag '(^|[^a-zA-Z0-9=])([a-zA-Z_][a-zA-Z0-9_]*), ?([a-zA-Z_][a-zA-Z0-9_]*) ?= ?\3, ?\2' across several Python code bases I've worked on, and indeed found very few examples. Here's one from Python's statistics.py: X, Y = self, other if (Y._sigma, Y._mu) < (X._sigma, X._mu): # sort to assure commutativity X, Y = Y, X NumPy has only one match that isn't in test code, in numpy/core/numeric.py:convolve if (len(v) > len(a)): a, v = v, a It's a bit more common in SciPy, like scipy/linalg/blas.py:_get_funcs which has: if prefer_fortran: module1, module2 = module2, module1 but even then, there are only 26 relevant matches across 421KLoC.
- dotancohen 4y ago> ag '(^|[^a-zA-Z0-9=])([a-zA-Z_][a-zA-Z0-9_]*), ?([a-zA-Z_][a-zA-Z0-9_]*) ?= ?\3, ?\2' Why are you checking `(^|[^a-zA-Z0-9=])` before the first variable? Why are you storing it? Wouldn't `^\s*` (beginning of line, then 0 or more whitespace, not stored) be simpler? I ask to learn, not critically.
- eesmith 4y agoThe exclusion test is to reduce false positives like: return open(filename, mode, encoding=encoding, errors=errors) ^^^^^^^^^^^^^^^^^^^^^^^ This case matches because of the under-caret'ed e, encoding=encoding, e You are right that requiring only leading whitespace would be clearer. I didn't think of it. I only wanted to eliminate those false positives I was seeing with my original test, which only had \2, \1. In thinking more about it, your whitespace-only gives a false negative for constructs like: progressbar/widgets.py:306: if not self.fill_left: rpad, lpad = lpad, rpad matplotlib/lib/matplotlib/widgets.py:1093: if vmin>vmax: vmin, vmax = vmax, vmin The reason I stored \1 was simply to get the grouping. I didn't recall the syntax for non-capturing groups, and it wasn't worthwhile to look up.
- dotancohen 4y agoI see, thank you. Targeting the if statements, but not the open() methods, is an interesting corner case that I would not have though about.
- eesmith 4y agoI did mine because I thought some people might write it: (a, b) = (b, a) so the grouping stands out better. Turns out I didn't find any examples of that.
- jasonhansel 4y agoIt's a bit more common in C when swapping pointers, since it can help you ensure that there's only one pointer to a given structure at any time, and it can simplify memory management in certain cases by letting you repurpose an existing allocation.
- forgotpwd16 4y agoInterestingly checking the implementation of this[0], it uses two temporary variables rather the commonly one. [0]:https://stackoverflow.com/a/62038590/1308965 https://stackoverflow.com/a/62038590/1308965
- Sebb767 4y agoBecause few languages have the ability to create a tuple with syntactic sugar on the fly that Python has. In PHP, you can similarly do the following: > list($a, $b) = [$b, $a]; Which is a bit more verbose than what Python does, but it's the same thing under the hood - you create a list/tuple, create a new list with swapped items at specific indices and then dissolve that list back to local variables. In the end, this is more expensive than the swap you'd do in C++^W other languages (EDIT: apparently C++ can also do this now), since it involves tuple creation. Although the compiler/JIT/interpreter will most likely recognize this pattern and optimize it to a `swap` call.
- adastra22 4y agoC++ can do multiple assignment now, fyi.
- tored 4y agoSince PHP 7.1 you can write [$a, $b] = [$b, $a];
- Koiwai 4y agoLots of newer languages can, like go and rust. BTW it's not "creating a tuple with syntactic sugar on the fly", I mean, if you think that's creating a tuple, obviously in lots of languages, that tuple is created by passing x/y's value, assigning to that anonymous tuple won't affect original x/y. The correct term should be destructuring assignment.
- Koiwai 4y agoIt's called destructuring assignment, it's not just for "in-place swap", and more over, it's about syntax, not performance. That article is talking about performance, and as many have pointed out, it's better just use a 3rd variable(when there's no destructuring assignment) to swap and let compiler do its work. I'm not saying syntax sugar is a bad thing.
- tialaramex 4y agoOr, express directly what you intended and let the compiler and library do it: e.g. https://doc.rust-lang.org/core/mem/fn.swap.html https://doc.rust-lang.org/core/mem/fn.swap.html