# Create a bijection between two lists

Is there a way to create a two-way association or a bijection between two lists of equal length? I know I can use AssociationThread twice, flipping the arguments, but how can I create a bijective function which associates each element in one list with an element of another, and vice-versa?

• In what way does the solution you mention fall short of what you want?
– Alan
Sep 13, 2016 at 3:21
• @Alan its more clunky: using two variables instead of one. Sep 13, 2016 at 3:24

A bijective function:

list1 = {1, 2, 3, 4};
list2 = {5, 6, 7, 8};
MapThread[(f[#] = #2; f[#2] = #) &, {list1, list2}]

f[2]
(* Out: 6 *)


And the AssociationThread solution that you mention:

f = <|AssociationThread[list1 -> list2], AssociationThread[list2 -> list1]|>;

f[2]
(* Out: 6 *)

a = {1, 2, 3, 4};
b = {5, 6, 7, 8};


A short variant of C.E.'s answer

f = <|Thread /@ {a -> b, b -> a}|>;

f[2]


6

a = {1, 2, 3, 4};
b = {5, 6, 7, 8};


A short variant of C.E.'s answer

f[lists__List] := Append @@ (AssociationThread @@@ {#, Reverse@#}) &@{lists};

{f[a, b][2], f[a, b][6]}

(*{6, 2}*)


Using PositionIndex with the 'default' argument of Lookup:

a=AssociationThread[list1,list2];

Lookup[a,#,Sequence@@PositionIndex[a][#]]&/@Join[list1,list2]

(* {5,6,7,8,1,2,3,4}  *)


As a function:

f[lista_,listb_]:=Module[{a=AssociationThread[lista,listb]},
Lookup[a,#,Sequence@@PositionIndex[a][#]]&]

bij=f[list1,list2];

bij/@Join[list1,list2]

(* {5,6,7,8,1,2,3,4}  *)

bij[1]

(* 5 *)

bij[5]

(* 1 *)