4
$\begingroup$

Let's say I have this enormous list of a million elements, and I want to access this list piecemeal in non-intersecting sublists of length ten. If

t = { (* long list*) }

I would like each sublist to be named

t1to10 = Partition[t, 10][[1]]
t11to20 = Partition[t, 10][[2]]

and so on, or equivalently,

t1to10 = t[[1;;10]]
t11to20 = t[[11;;20]]

etc. However, I don't have the luxury of being able to define $10^5$ different variables. Is there a convenient way of defining all my variables in the exact pattern I want, e.g.

tXXtoYY = Partition[t, 10][[YY/10]]
(* where XX = YY/10 - 9 *)

or

tXXtoYY = t[XX;;YY]
$\endgroup$
7
  • 1
    $\begingroup$ Why not use Span[] then? $\endgroup$ Mar 8, 2016 at 17:03
  • $\begingroup$ @J.M. I was on the fence about using Partition over Span when I was first writing the question, but I settled on one and figured someone would point out a better/easier option. I've edited my question to include the latter. $\endgroup$
    – user170231
    Mar 8, 2016 at 17:08
  • $\begingroup$ l = RandomReal[{0, 1}, 10^6]; myP[n_Integer] := l[[10 (n - 1) + 1 ;; 10 n]]; Print[myP[1], myP[10^5]] $\endgroup$ Mar 8, 2016 at 17:15
  • 2
    $\begingroup$ So you're essentially copying the entire huge list piecemeal to smaller lists? That seems like it wastes a lot of memory. What is the intended purpose? Instead, what I would do is define a function that extracts the desired parts from the big list when needed. $\endgroup$
    – Jens
    Mar 8, 2016 at 17:16
  • $\begingroup$ @Jens In reality, the huge list has length 12 326, and the lists are composed of text strings - some lengthier than others - that I'm supposed to test in a search engine. The segmentation of the megalist was intended to make it easier for me to keep track of which inputs have been tested. $\endgroup$
    – user170231
    Mar 8, 2016 at 17:38

2 Answers 2

11
$\begingroup$

Here's a pretty natural way, I think, that almost matches your variable names.

list = Range[51];  (* for testing *)
t[x_Integer, y_Integer] /; y == 9 + x := t[x, y] = list[[x ;; y]]
t[11, 20]
(* {11, 12, 13, 14, 15, 16, 17, 18, 19, 20} *)

Using t[11, 20] rather than t11to20 serves the purposes of being easily functionalized, is just as readable, allows you to directly index the variable names, and allows memoization (i.e. once t[11, 20] has been evaluated once, it's stored in memory from there on out).


I recommend against doing tXXtoYY, because the programmatic construction of such a variable name is ugly and unnatural, and it doesn't allow you to manipulate the different lists programmatically (and functionally).

$\endgroup$
1
  • $\begingroup$ This works for me! Thanks for the suggestion. $\endgroup$
    – user170231
    Mar 8, 2016 at 17:39
4
$\begingroup$

Maybe it's worth putting up an answer that addresses the "naming pattern" part mentioned in the question. As I mentioned in my comment, I don't see why you'd want to store the parts individually in separate variables, so I will focus only on a function that allows you to use exactly the variable names that you want, but without assigning any values to them. That potentially saves a lot of memory.

Then the question reduces to extracting the correct parts of a big list, given a symbol with the naming convention you required. Here is the answer to that question:

t = RandomWord["CommonWords", 100];

u = RomanNumeral[Range[100]];

getNamed[s_Symbol] := Module[{name = SymbolName[s]},
  Part[Symbol @@ StringCases[name, LetterCharacter .., 1], 
   Apply[Span, ToExpression@StringCases[name, NumberString]]]]

getNamed[t1To10]

(*
==> {"holler", "perturbation", "inform", "grind", "unstudied", \
"knucklehead", "trefoil", "uracil", "carhop", "deceptively"}
*)

getNamed[t11To20]

(*
==> {"labeled", "forswearing", "laurels", "welt", "foundling", \
"reservation", "popularize", "foolishly", "dinette", "warble"}
*)

getNamed[u31To40]

(*
==> {"XXXI", "XXXII", "XXXIII", "XXXIV", "XXXV", "XXXVI", \
"XXXVII", "XXXVIII", "XXXIX", "XL"}
*)

The main ingredient in the function getName is SymbolName, which converts the input to a string on which I then do pattern matching to extract the name of the large list and the parts.

$\endgroup$
3
  • $\begingroup$ What is the benefit of using SymbolName versus ToString here? $\endgroup$
    – march
    Mar 8, 2016 at 18:39
  • $\begingroup$ @march With the specific naming convention of the OP, there's no difference to ToString, I'd say. The difference is their handling of Contexts, which isn't an issue here. $\endgroup$
    – Jens
    Mar 8, 2016 at 19:12
  • $\begingroup$ I see (sort of: not really versed in dealing with Contexts). Anyway, this is definitely a clever way of actually answering the OP's request that avoids the unnaturalness of programmatically creating variable names. +1 $\endgroup$
    – march
    Mar 8, 2016 at 20:05

Your Answer

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

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