In comparison, I think that := is much simpler.
In this case that's true, but a small modification:
updates = {
y: do_something_to(potential_update)
for x in need_initialization_nodes
for y in [x, *x.synthetic_inputs()]
if potential_update is not None
given potential_update = command.create_potential_update(y)
}
Shows the flexibility of this given syntax vs ":="
If we think of "given" as just inserting a line with variable-definitions before the preceding statement, it seems clear that:
updates = {
y: potential_update
given potential_update = command.create_potential_update(y)
for x in need_initialization_nodes
for y in [x, *x.synthetic_inputs()]
if potential_update is not None
}
Should raise a NameError: name 'potential_update' is not defined, and
updates = {
y: potential_update
for x in need_initialization_nodes
for y in [x, *x.synthetic_inputs()]
given potential_update = command.create_potential_update(y)
if potential_update is not None
}
Should raise a NameError: name 'y' is not defined.
For safety it seems reasonable that if a variable is "given" in a comprehension, trying to refer to it (even if it defined in the enclosing scope) before the inner-definition will result in a NameError.