Group Abstract Group Abstract

Message Boards Message Boards

0
|
8.4K Views
|
11 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Create named empty lists, name coming from another list?

Posted 8 years ago
POSTED BY: Paul Cleary
11 Replies
Posted 8 years ago
POSTED BY: Paul Cleary

Paul,

The suggestions you have gotten so far have all been all excellent. I will add one more idea in the mix in case it might better suit your problem.

I like to use the assignments in MMA to make a dictionary. For example, you can enter

junk["one"] = {12}
junk["two"] = {4,8}

You can see all of your assignments with ?junk or Definition[junk] or programmatically with DownValues[junk].

The advantage is that you do not need to create new symbols manually or manage them. Using Marco's example (but making a string out of it since I think you said you are handling large strings)

Set up some lists:

In[6]:= names = RandomSample[WordList[], 10]

Out[6]= {"steps", "highlight", "puppeteer", "cleanness", \
"credential", "nonstarter", "ablaze", "telegraphically", "stoppage", \
"heads"}

In[7]:= tableentries = 
 Table[StringRiffle[RandomChoice[names, 4], " "], 20]

Out[7]= {"cleanness cleanness ablaze heads", "telegraphically \
nonstarter credential credential", "cleanness credential \
telegraphically stoppage", "stoppage heads heads telegraphically", \
"puppeteer ablaze nonstarter telegraphically", "telegraphically \
stoppage credential nonstarter", "telegraphically steps ablaze \
cleanness", "credential stoppage ablaze credential", "heads \
nonstarter puppeteer stoppage", "cleanness ablaze highlight \
cleanness", "ablaze heads nonstarter highlight", "ablaze nonstarter \
heads heads", "stoppage nonstarter steps heads", "cleanness cleanness \
ablaze telegraphically", "nonstarter telegraphically credential \
stoppage", "ablaze puppeteer nonstarter cleanness", "highlight ablaze \
cleanness cleanness", "puppeteer cleanness puppeteer ablaze", \
"stoppage nonstarter stoppage highlight", "credential heads \
credential ablaze"}

To create the dictionary programmatically create a function to assign the dictionary value, testing if its the first time it is used -- either set the first value or just append the latest value.

tmpify[x_String, val_] := 
 If[Head[tmp[x]] === tmp, tmp[x] = {val}, 
  tmp[x]  = Append[tmp[x], val]]

Now you can use it by first clearing all old entries in tmp and then mapping the function over the table of values and Map it a second time over the list of names to give the location of every name in every string in the table:

Clear[tmp]

Map[Function[name, 
   MapIndexed[
    If[StringCount[#1, ___ ~~ name ~~ ___] > 0, tmpify[name, #2[[1]]],
       Nothing] &, tableentries]], names];

This is the result:

enter image description here

This approach would be very fast when doing many lists and it would be easy to reference the result either with

tmp["steps"]

or

tmp[names[[1]]]

I hope this helps.

Regards,

Neil

POSTED BY: Neil Singer

Summing up the linked topic:

ToExpression[
  # <> "temp"
, StandardForm
, Function[symbol, symbol = {}, HoldAll]
]&  /@ {"one", "bus", "tree", "townhouse"}
POSTED BY: Kuba Podkalicki
Posted 8 years ago
POSTED BY: Paul Cleary

In order to handle cases where those symbols already have values you need to incorporate the third argument of ToExpression, see:

POSTED BY: Kuba Podkalicki
Posted 8 years ago

Thank you for the link Kuba, I look forward to reading it.

POSTED BY: Paul Cleary
POSTED BY: Marco Thiel
Posted 8 years ago

Dear Marco

I appreciate your time on this and indeed we are getting closer to my goal, those list's are created as you say and I can append to them by specifically writing into them, but my goal is to add into each list many thousands of lines of text that is parsed from a much bigger list where some lines of text contains the name of the created list. (if you see what I mean). Secondly there could be up to 60 of these created named lists, non of which I need to know the names of nor do I want to see them and I want it to be all automatic. So in a nutshell I have a large file consisting of multiple millions of lines of text, within these lines of text are anywhere from 1 to 60 names, the names can be extracted as they always appear at a certain position in the line and this forms the basis of my named list. I now want to create as many empty lists as there are names and on the second pass through the large file extract only those lines that contain the name and put it in the newly created temp list so at the end of the second pass each of the lists say onetemp now contains only those line that also contain one (one is a bad example I know) the names would be actual names of characters. So I need to be able to index the list of lists and then add information into them. Sorry if this is getting long.

Edit

If we add this to the line

nametemp = Map[Set[#, {}] &, ToExpression[# <> "temp"] & /@ names]

I can index nametemp as in nametemp[[1]] and use Reap and Sow and it does seem to work, it seems to add it to what starts as an empty list, yet if you directly type the name of the list it is still empty. Wonder if this is intended?

Cheers,

POSTED BY: Paul Cleary

Dear Paul,

all the lists are in fact created. If you just type

onetemp

you will see that it gives an empty list. If you want to add something to the list you can do:

AppendTo[onetemp,5]

and it will add 5 to that list. If you then execute

onetemp

it will be a list with 5 as the only element. I guess that the output was a bit confusing. You can suppress it with a ; at the and of the line.

Alternatively, this works, but is longer than my original solution:

tempnames = ToExpression[# <> "temp"] & /@ names; 
Do[tempnames[[i]] = {}, {i, 1, Length[names]}]

Also, procedural programming is discouraged.

Cheers,

Marco

POSTED BY: Marco Thiel
Posted 8 years ago

Hi Marco

Thanks for the quick reply, however, it doesn't seem to do what I want, your program creates a list of empty {} . If I want to create a named empty list I would type onetemp={} Then I could access onetemp and add data into it, how would I do that in your example?

POSTED BY: Paul Cleary

Hi,

something like this?

names = {"one", "bus", "tree", "townhouse"};
Map[Set[#, {}] &, ToExpression[# <> "temp"] & /@ names]

Best wishes, Marco

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