3
$\begingroup$

The following code:

list=Table[<\"number"->i|>,{i,1,100}];
list[[20]]["number"]

list[[1]]
AssociateTo[list[[1]],"number"->101];
list[[1]]

Results in...

20
<|number->1|>
<|number->101|>

as it should. Now with the same code but using a variable I get an error:

list=Table[<\"number"->i|>,{i,1,100}];
list[[20]]["number"]

k=1;
list[[k]]
AssociateTo[list[[k]],"number"->101];
list[[k]]

results in...

20
<|number->1|>
AssociateTo: Part specification k is neither a machine-sized integer nor a list of machine-sized integers. 
<|number->1|>

What's going on here?

$\endgroup$
1
  • 1
    $\begingroup$ <\ is not valid. I assume you had <| in the actual code you ran. Please make sure you paste the exact code you used yourself. You'd be surprised to learn how often a problem turns out to be due to a difference in what someone runs vs what they show here (however, in your case, it is not). $\endgroup$
    – Szabolcs
    Sep 12, 2018 at 16:09

1 Answer 1

4
$\begingroup$

This is because AssociateTo has the HoldFirst attribute and does not evaluate its first argument before handling it. Even if k=1, it only sees list[[k]] and not list[[1]]. After you understand the Hold... attributes, you will find this to be standard and logical behaviour.

The direct workaround is to substitute in the literal value of k:

With[{k=k}, AssociateTo[ list[[k]], ... ] ]

However, in this specific case, I suggest simply using

list[[k, "number"]] = 101

Set also has the HoldFirst attribute, but it's smarter about handling its first argument. It will do that substitution for you automatically.

Unlike AssociateTo, I would not call the behaviour of Set simple or standard. It does complicated things in the background. But I also think that it's much more user-friendly (especially to those who don't yet know about Hold... attributes).

$\endgroup$

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .