Expression that returns mutated list
Question:
I’m looking for a single expression, mutates an element and returns the modified list
The following is a bit verbose
# key=0; value=3; rng=[1,2]
[(v if i != key else value) for i, v in enumerate(rng)]
Edit:
I’m looking for a way to inline the following function in a single expression
def replace(rng: List, key: int, value):
a = list(rng)
a[key] = value
return a
Edit 2: the code that actually motivated this question
class TextDecoder(nn.Module):
def forward(self, x: Tensor, kv_cache: Tensor):
kv_cache_write = torch.zeros((_:=list(kv_cache.shape))).__setitem__(-2, x.shape[-1]) or _)
...
Answers:
# key=0; value=3; rng=[1,2]
print(rng.__setitem__(key, value) or rng)
If you don’t want to modify the original list rng
, you can do
print((_:=list(rng)).__setitem__(key, value) or _)
unfortunately this leaks the variable _
.
Try list concatenation:
key = 0
value = 3
rng = [1, 2]
out = rng[:key] + [value] + rng[key+1:]
print(out)
rng[:key]
is a copy of the list up to the key (exclusive), [value]
is a new list where the only element is value
, and rng[key+1]
is a copy of the list from the key on (exclusive). Concatenate these together, and you get a copy where the key is replaced.
Maybe better than list concatenation:
[*rng[:key], value, *rng[key+1:]]
Another:
[a for a, a[key] in [(rng[:], value)]][0]
Or if you are just assigning the result to a variable (as discussed) you can do:
a, a[key] = rng[:], value
I’m looking for a single expression, mutates an element and returns the modified list
The following is a bit verbose
# key=0; value=3; rng=[1,2]
[(v if i != key else value) for i, v in enumerate(rng)]
Edit:
I’m looking for a way to inline the following function in a single expression
def replace(rng: List, key: int, value):
a = list(rng)
a[key] = value
return a
Edit 2: the code that actually motivated this question
class TextDecoder(nn.Module):
def forward(self, x: Tensor, kv_cache: Tensor):
kv_cache_write = torch.zeros((_:=list(kv_cache.shape))).__setitem__(-2, x.shape[-1]) or _)
...
# key=0; value=3; rng=[1,2]
print(rng.__setitem__(key, value) or rng)
If you don’t want to modify the original list rng
, you can do
print((_:=list(rng)).__setitem__(key, value) or _)
unfortunately this leaks the variable _
.
Try list concatenation:
key = 0
value = 3
rng = [1, 2]
out = rng[:key] + [value] + rng[key+1:]
print(out)
rng[:key]
is a copy of the list up to the key (exclusive), [value]
is a new list where the only element is value
, and rng[key+1]
is a copy of the list from the key on (exclusive). Concatenate these together, and you get a copy where the key is replaced.
Maybe better than list concatenation:
[*rng[:key], value, *rng[key+1:]]
Another:
[a for a, a[key] in [(rng[:], value)]][0]
Or if you are just assigning the result to a variable (as discussed) you can do:
a, a[key] = rng[:], value