Reputation: 58662
Please see the code here
move_from, move_to = [
(item['path'], prev_item['path']),
(prev_item['path'], item['path']),
][item['op'] == 'add']
What is assigned to move_from and move_to. It looks like double assignment, but don't see two on the right (I am a non python programmer) I am trying to port to Javascript, how would it look like?
Thanks.
Upvotes: 0
Views: 590
Reputation: 785
This
[
(item['path'], prev_item['path']),
(prev_item['path'], item['path']),
]
is a Python list. The first (0) item is
(item['path'], prev_item['path'])
and the second (1) is
(prev_item['path'], item['path'])
the boolean here
[item['op'] == 'add']
evaluates to True of False ( 1 or 0 ) so that one of those items is chosen.
For example, if item['op'] does equal 'add', then the result is
move_from, move_to = prev_item['path'], item['path']
EDIT: You asked for JS code. This might do it. NOTE that I've assumed most variables are global since I don't know in what context you will use this.
String.prototype.rsplit = function(sep, maxsplit) {
var split = this.split(sep);
return maxsplit ? [ split.slice(0, -maxsplit).join(sep) ].concat(split.slice(-maxsplit)) : split;
}
function _optimize_using_move(prev_item, item) {
prev_item['op'] = 'move';
if (item['op'] == 'add') {
prev_item['from'] = prev_item['path'];
prev_item['path'] = item['path'];
} else {
var parts = move_from.rsplit('/', 1);
head = parts[0];
move_from = parts[1];
move_from = int(item['path']) - 1;
prev_item['from'] = head + '/' + item['path'];
prev_item['path'] = prev_item['path'];
}
}
Upvotes: 5
Reputation: 9612
Split it into two steps.
First
print ['a', 'b'][0 == 1]
# 'a'
print ['a', 'b'][0 == 0]
# 'b'
In python, if you use a boolean value as array index, False
is considered as 0, and True
as 1. So in your case, the value of
[
(item['path'], prev_item['path']),
(prev_item['path'], item['path']),
][item['op'] == 'add']
should be (item['path'], prev_item['path'])
if item['op']
is not "add"
otherwise (prev_item['path'], item['path'])
.
Then the assignment
a, b = (0, 1)
is very similar to a = 0
, b = 1
. In your case, if item['op']
equals to "add"
, the result is
move_from = prev_item['path']
move_to = item['path']
Although it is completely valid to use a boolean value, I don't suggest program like that. A more common convention is to use CONSEQUENCE if PREDICATE else ALTERNATIVE
(like PREDICATE ? CONSEQUENCE : ALTERNATIVE
in C-like language)
move_from, move_to = (prev_item['path'], item['path']) \
if item['op'] == 'add' else \
(item['path'], prev_item['path'])
Since there's no tuple assignment in JS, I think a simple way is
if (item['op'] === 'add') {
move_from = prev_item['path'];
move_to = item['path'];
} else {
move_from = item['path'];
move_to = prev_item['path'];
}
Upvotes: 3
Reputation: 12140
What you see here is a little trick pythonistas often use in code golf. Let break this code down.
move_from, move_to = [
(item['path'], prev_item['path']),
(prev_item['path'], item['path']),
][item['op'] == 'add']
First :
[item['op'] == 'add']
what this does is compares item['op']
to add
.
This comparison then returns a Boolean value, i.e True
or False
In python True
and False
are essentially equivalent to 1
and 0
respectively.
Now essentially we have:
move_from, move_to = [
(item['path'], prev_item['path']),
(prev_item['path'], item['path'])
][<0 or 1>]
Now depending on the whether the comparisons was true or false, the first or the second element of this array is returned.
In both cases the object returned (or selected from the array/list) is a tuple of the form:
(a, b)
.
Now Python does something called tuple unpacking.
So when you see:
move_from, move_to = (a, b)
it essentially means:
move_from = a
and
move_to = b
I hope that clarifies how this code works.
Upvotes: 0
Reputation: 2786
As sdolan said, the [item['op'] == 'add']
will select which of the two tuples will be used to refer move_from and move_to.
Try this simplification yourself, and switch [True] to [False] for comparison:
move_from, move_to = [(1, 2), (3, 4),][True]
print(move_from)
print(move_to)
Upvotes: 1