12

If I have a simple list, say {1, 2, 3}, and I want to extract a subset of the elements, what is the correct syntax? e.g.

{ i, _, j } = {1, 2, 3}

I want i = 1 & j = 3 (which works), but I get the following warning:

Set::nosym: _ does not contain a symbol to attach a rule to.

so clearly I am using the wrong placeholder for elements I wish to ignore.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
fhusb
  • 123
  • 5
  • 1
    The warning appears because you are trying to assign 2 to _. There are a lot of ways to do what you need: {i, j} = Drop[{1,2,3}, {2}] for example. – Kuba Aug 09 '13 at 10:15
  • 1
    It should be noted that often this type of situation is easily avoidable by instead doing something like: {i,j}={1,2,3}[[{1, 3}]]. – jVincent Aug 09 '13 at 13:01

2 Answers2

14

Turn off the warning

It should be noted that we can treat Set::nosym as a warning message rather than an error, and simply turn it Off:

Off[Set::nosym]

{i, _, j} = {1, 2, 3};

{i, j}
{1, 3}

throw-away Symbol

You could asko designate a Symbol for this purpose as a kind of dev/null, using e.g. $Post to clear it every time. I'll pick \[DoubleDagger], entered EscddgEsc and displayed as :

$Post = ((‡ =.; #) &);

Now you could make your assignment:

{i, ‡, j} = {1, 2, 3};

The value of is cleared after each evaluation so as not to take up memory.


For reference, the definition of $Post above is not entirely neutral. For example, by default entering Sequence @@ {1, 2, 3} will return Sequence[1, 2, 3] whereas with the definition it will return 1. The ugly but proper definition would be something like:

$Post = Function[x, ‡ =.; Unevaluated@x, HoldAllComplete];

Since $Post is only one way to clear the Symbol I didn't want to clutter the top of the answer with this code. Other methods would be RunScheduledTask, CellEpilog, etc.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
1

The equal sign is trying to assign the list {1,2,3} to the left hand side {i,_,j} and you cannot assign 2 to _.

Try the following code:

list = {a, b, c};
Extract[list, {{1}, {3}}]
{First[list], Last[list]}
Replace[list, {i_, _, j_} :> {i, j}]
Hector
  • 6,428
  • 15
  • 34
  • 2
    Thanks. I was aware of the more verbose syntax for Extract which will certainly work, but I was hoping there was a more natural, concise syntax similar to that which I suggested? – fhusb Aug 09 '13 at 10:34