7
$\begingroup$

I have an association of the following form :

assoc = Association[a -> {1, 2, 3}, b -> {5, 6, 7}]

<|a -> {1, 2, 3}, b -> {5, 6, 7}|>

(the size of actual lists in assoc is 30).

If I want to change the value of the list associated to a in the following manner: assoc[a][[1]] = 2, it does not work. I understand why mostly, I have looked it up (some mutability stuff e_e) !

by searching the forum, I didn't find any better than:

temp=assoc[a]
temp[[1]]=2
AssociateTo[assoc,a->temp]

I have two questions :

Between changing in place the value of a very big list (very) or changing the value of a very big association like demonstrated above, which is faster ?

Second, is there a better way to change the value of elements of the list associated to key a in assoc ?i.e. without the copying process.

Thank you.

$\endgroup$
1
  • 5
    $\begingroup$ You need to use single Part call and wrap the key(s) in Key: assoc[[Key[a], 1]] = 2 $\endgroup$ Commented Apr 30, 2020 at 18:23

3 Answers 3

2
$\begingroup$
asc = Association[a -> {1, 2, 3}, b -> {5, 6, 7}];

Using ReplaceAt (new in 13.1)

ReplaceAt[_ :> 2, {Key[a], 1}] @ asc

<|a -> {2, 2, 3}, b -> {5, 6, 7}|>

Using MapAt

MapAt[2 &, {Key[a], 1}] @ asc

<|a -> {2, 2, 3}, b -> {5, 6, 7}|>

If we want to change asc inline (see comment) we can use ApplyTo (new in 12.2)

asc //= MapAt[2 &, {Key[a], 1}];

asc

<|a -> {2, 2, 3}, b -> {5, 6, 7}|>

$\endgroup$
2
$\begingroup$

You are correct that

assoc[a][[1]] = 2

does not work, because it allows assoc[a] to evaluate first. But

assoc[[Key[a],1]] = 2

works just fine. If the association keys are strings then the Key wrapper is not needed.

$\endgroup$
1
$\begingroup$
assoc = Association[a -> {1, 2, 3}, b -> {5, 6, 7}]

Using SubsetMap:

SubsetMap[{2} &, assoc, {{1, 1}}]

(*<|a -> {2, 2, 3}, b -> {5, 6, 7}|>*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.