Message Boards Message Boards

0
|
7567 Views
|
3 Replies
|
5 Total Likes
View groups...
Share
Share this post:

Increment a lists elements based on the content of another list.

Posted 10 years ago

I am trying to record how many one's, twos,..., sixes are in a list. Below is what I have tried to do and the resulting output. There are two things I would like to know:

1) What is the proper way to do this?
2) Why does the below code not work?
3) What is the last line telling me, should I be able to understand my error from this output?

Thanks for your help Mark

In[46]:= 
test = {0, 0, 0, 0, 0, 0}
test[[#]]++ & /@ {1, 1, 3, 2, 1, 0}
test

Out[46]= {0, 0, 0, 0, 0, 0}

Out[47]= {0, 1, 0, 0, 2, List}

Out[48]= (1 + List)[3, 1, 1, 0, 0, 0]
POSTED BY: Mark Henwood
3 Replies

Dear Mark,

is there a special reason why you do not wish to use the Tally command?

Sort[Tally[{1, 1, 3, 2, 1, 0}]]

It is quite fast even if your lists get longer:

Sort[Tally[RandomInteger[5, 1000000]]]

Your solution does not work for several reasons. One is that one of the indices is 0. test[[0]] asks for the Head of test, which is List. This is one reason why you get a funny output. I would not recommend it at all, but

test = {0, 0, 0, 0, 0, 0}
(test[[# + 1]] = test[[# + 1]] + 1) & /@ {1, 1, 3, 2, 1, 0}; test

would work. The list test, would be filled with zeros at the end according to the length of the original field. The semicolon suppresses the output, because the first bit is a very strange way of defining a loop, and you do not want to see the intermediate results. Your output is basically how often the number in the input list has occurred up to that stage, which is not what you want. I also added a "+1" so that you get around the problem of the Head of the list, which is test[[0]]. Something more standard would look like this:

test = {0, 0, 0, 0, 0, 0}; inputsequence = {1, 1, 3, 2, 1, 0};
Do[ test[[inputsequence[[i]] + 1]] = 
  test[[inputsequence[[i]] + 1]] + 1, {i, 1, 
  Length[inputsequence]}]; test

Cheers,

Marco

POSTED BY: Marco Thiel
Posted 10 years ago

Thanks Marco, Sorry it took so long to get back to you, travel and life got in the way.
You answered both questions wonderfully, I did not know about the Tally command and for that reason stubbornly refused to use it :) It will do the job nicely. Also, the [[0]] "error" shows the difference between knowing something and understanding it. Thanks to you I understand what having the head of something show up in the output means.

Thanks for your time, Mark

POSTED BY: Mark Henwood
Posted 10 years ago

Just some other approaches to tallying (no advantages but to illustrate Mathematica diversity):

list = {1, 1, 3, 2, 1, 0}

Tallying:

{#, Count[list, #]} & /@ Union[list]

yields: {{0, 1}, {1, 3}, {2, 1}, {3, 1}}

Unsorted:

Last@Reap[Sow[1, #] & /@ list, _, {#1, Total@#2} &]

yields: {{1, 3}, {3, 1}, {2, 1}, {0, 1}}

First@# -> Length@# & /@ Gather[list]

yields: 1 -> 3, 3 -> 1, 2 -> 1, 0 -> 1}

GroupBy[list, # &, Length]

yields assoiation: <|1 -> 3, 3 -> 1, 2 -> 1, 0 -> 1|>

POSTED BY: Mark Dooris
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract