While partitioning the elements in a list using GatherBy, can I correspondingly partition the elements of an unrelated list?

Here is another approach. The basic idea is that GatherBy creates a list of representatives corresponding to the input, then partitions the input based on those representatives. We can see this in action with Trace. Here is an example:

func[x_] := Mod[x, 3]
Trace[GatherBy[{1, 2, 3, 4, 5}, func], TraceInternal->True]

{GatherBy[{1,2,3,4,5},func],{func/@{1,2,3,4,5},{func[1],func[2],func[3],func[4],func[5]},{func[1],Mod[1,3],1},{func[2],Mod[2,3],2},{func[3],Mod[3,3],0},{func[4],Mod[4,3],1},{func[5],Mod[5,3],2},{1,2,0,1,2}},{{1,4},{2,5},{3}}}

Notice how GatherBy internally computes func /@ {1,2,3,4,5} to create the list of representatives {1, 2, 0, 1, 2}. This list of representatives is then used to partition the input. So, to answer your question, we can override the Map so that it uses an alternate list of representatives. Here is a function that does this:

GatherByList[list_, representatives_] := Module[{func},
    func /: Map[func, _] := representatives;
    GatherBy[list, func]
]

For your example:

GatherByList[list2, Mod[list1, 3]]

{{"It", "the", "man", "shall"}, {"is", "morning", "complained", "consider"}, {"only", "the", "I", "nothing"}}

Let's compare timings with the accepted answer:

list1 = Range[10^6];
list2 = RandomReal[1, 10^6];

r1 = GatherByList[list2, Mod[list1, 3]]; //RepeatedTiming
r2 = GatherBy[Transpose[{list1, list2}], Mod[#[[1]], 3] &][[All, All, 2]]; //RepeatedTiming

r1 === r2

{0.013, Null}

{1.36, Null}

True

So, GatherByList is 2 orders of magnitude faster.


list1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 
list2 = {"It", "is", "only", "the", "morning", "the", "man", "complained", "I", "shall", 
         "consider", "nothing"}; 
GatherBy[Transpose[{list1, list2}], Mod[#[[1]], 3] &][[All, All, 2]]

(* {{"It", "the", "man", "shall"}, {"is", "morning", "complained",  "consider"}, 
    {"only", "the", "I", "nothing"}} *)

list1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
idx = GatherBy[list1, Mod[#, 3] &]

list2 = {"It", "is", "only", "the", "morning", "the", "man", "complained", 
      "I", "shall",   "consider", "nothing"};

Part[list2, #] & /@ idx

Mathematica graphics