A dictionary with string keys and string values.


The 'inversedict' of this dictionary.

How to make an inversedict

An inversedict is a dictionary with string keys and string array values. The keys are the values from the original dictionary, and the values are the keys from the original dictionary with that value from the original dictionary.

An example

["Clyde": "blue", "Sarah": "blue", "Fred": "green"]
["blue": ["Clyde", "Sarah"], "green": ["Fred"]]

This is , so shortest code in bytes wins!

  • 1
    \$\begingroup\$ Does our language need to have dictionaries? Can we use a list of tuples? \$\endgroup\$
    – xnor
    Nov 18, 2016 at 4:14
  • 1
    \$\begingroup\$ @xnor, that's allowed if your language does not have dictionaries \$\endgroup\$
    – Daniel
    Nov 18, 2016 at 4:14
  • \$\begingroup\$ Wait, isn't a defaultdict a dictionary that defaults to some value or function on a missing key? This looks like an "inverse" of a dictionary. \$\endgroup\$
    – xnor
    Nov 18, 2016 at 4:16
  • \$\begingroup\$ @xnor, yeah that makes a lot more sense :) \$\endgroup\$
    – Daniel
    Nov 18, 2016 at 4:17
  • 3
    \$\begingroup\$ Haskell calls this flipAL with AL for association list (from Data.Lists). You might want to ban built-ins that do this. \$\endgroup\$
    – xnor
    Nov 18, 2016 at 4:25

25 Answers 25


Mathematica, 28 bytes


The input is an Association, the output is an Association too.



Convert the input Association to a List of Rules.

Reverse/@ ...

Reverse the Rules.

Merge[ ... ,#&]

Merge all Rules, grouping duplicates with a List and then with the identity operation. Creates an Association.


 <|"Clyde" -> "blue", "Sarah" -> "blue", "Fred" -> "green"|>

<|"blue" -> {"Clyde", "Sarah"}, "green" -> {"Fred"}|>


Python 2, 54 bytes

lambda i:{i[k]:[a for a in i if i[a]==i[k]]for k in i}


f=lambda i:{i[k]:[a for a in i if i[a]==i[k]]for k in i}
print f({"Clyde": "blue", "Sarah": "blue", "Fred": "green"})


{'blue': ['Sarah', 'Clyde'], 'green': ['Fred']}

Brachylog, 10 bytes


Try it online!

Takes input as a list of [key, value] pairs through the input variable, and outputs a list of [value, [keys]] pairs through the output variable.

 ᵍ            Group the elements of
              the input
t             by their last elements.
         ᵐ    For each group,
   t          its last element
  ⟨     ⟩     paired with
      hᵐ      the first element of every element
     ʰ        with the first element of the pair being replaced by
    t         its last element
         ᵐ    is the corresponding element of
              the output.

...such an eloquent explanation...


Rust, 127 bytes

use std::collections::HashMap as H;|m:H<String,String>|{let mut n=H::new();for(k,v)in m{n.entry(v).or_insert(vec![]).push(k)}n}

Try it online!


Pyth, 10 bytes


Try it online!

uXeHG]hHQH   Implicit: Q=eval(input()), H={} (empty dictionary)
u       Q    Reduce elements of Q...
         H   ... starting with an empty dictionary...
             ... current value is G, next value is H:
 X  G          Add to G...
  eH           ... with key as last element of H (i.e. value from original input dictionary)...
     ]hH       ... value as first element of H, wrapped in a list
               This adds a new single-element list if the key is not alrady present, or concatenates values if it is

Japt, 9 7 bytes

Input is as a 2D-array: [[key,value],[key,value],...].
Output is as a 3D-array: [[value,[key,key,...]],[value,[key,key,...]],...].

If we can ouput the pairs in reverse order then the Ô can be removed, an the v replaced with o to save a byte.


Try it

üÌ®ÕÔvÎ     :Implicit input of array
ü           :Group and sort by
 Ì          :  Last element of each
  ®         :Map
   Õ        :  Transpose
    Ô       :  Reverse
     v      :  Modify first element
      Î     :    Get first element

If output must be a 2D-array then:

10 8 bytes


Try it

The _, essentially, serves the same purpose as the ® above and the c flattens the array by one level afterwards.


Lua, 82 Bytes

function(t)g={}for k,v in pairs(t)do g[v]=g[v]or{}g[v][#g[v]+1]=k end return g end

An anonymous function which takes a table as an input and outputs the inverse dict.

Commented and Ungolfed.

function(t)                     #Anonymous Function.
    g={}                        #Define the output array.
    for k,v in pairs(t) do      #For each value in the input by key value pairs.
        g[v]= g[v] or {}        #Set the value of the output dictionary with the key v, to either itself, or a new table if it's null.
        g[v] [#g[v]+1] = k      #Set a new value (#g[v]+1 is the key that is +1 the count, lua is 1 indexed) to the key.
    end                         #This loop will append values with the same 'key', instead of set. However, makes all output in table form.
    return g                    #Output g
end                             #End

JavaScript (ES6), 57 bytes

d=>eval("r={};for(i in d)(r[j=d[i]]=r[j]||[]).push(i);r")

Input and output are as Objects, e.g. {"Clyde": "blue", "Sarah": "blue", "Fred": "green"}

  • \$\begingroup\$ Just wondering since I don't know much about JS, why do you need to put this in an eval()? \$\endgroup\$
    – Kade
    Nov 18, 2016 at 14:31
  • \$\begingroup\$ @Shebang You don't have to, but d=>{r={};for(i in d)(r[j=d[i]]=r[j]||[]).push(i);return r} is one byte longer because of the return. \$\endgroup\$ Nov 18, 2016 at 14:37
  • \$\begingroup\$ Ah, that explains it :) Nice answer! \$\endgroup\$
    – Kade
    Nov 18, 2016 at 14:50

C#6, 136 bytes

using System.Collections.Generic;using System.Linq;ILookup<string,string>F(Dictionary<string,string>d)=>d.ToLookup(x=>x.Value,x=>x.Key);

repl.it demo

Seriously, do I really need to ungolf this? Just create an ILookup with input value as output key and input key as output value.


C++17, 158 bytes

[](auto m){std::map<std::string,std::vector<std::string>>n;for(auto x:m)n[x.second].push_back(x.first);return n;}

Ungolfed and usage:


auto f=
[](auto m){
 std::map<std::string,std::vector<std::string>>n;  //using namespace is equally long
 for(auto x:m)
 return n;

using namespace std;

int main(){
 map<string,string> m={
 auto n = f(m);
 for (auto x:n){
  cout << x.first << ": ";
  for (auto y:x.second)
   cout << y << ", ";
  cout << "\n";
 cout << "\n";

Factor, 27 bytes

[ [ last ] collect-key-by ]

running the above code in the listener


05AB1E, 10 (or 9) bytes


Input as [[key,value],[key,value],...]; output as [[value,[keys]],[value,[keys]],...].

Try it online.

If it's allowed to output as [[[keys],value],[[keys],value],...] instead, it can be 1 byte less by removing the trailing R:
Try it online.


.¡ }        # Group the pairs of the (implicit) input-list by:
  θ         #  Their last item
    ε       # Then map over each group of pairs:
     ø      #  Zip/transpose; swapping rows/columns
      `     #  Pop and push the list of keys and list of values separately to the stack
       н    #  Pop and leave just the first item of the values-list
        ‚   #  Pair it with the keys-list
         R  #  (optional: Reverse the [[keys],value] pair to [value,[keys]])
            # (after which the result is output implicitly)

JavaScript, 47 bytes

Input as a 2D array, output as an object.


Try it online!


Jelly, 8 bytes


Try it online!

Input as a list of [key, value] pairs, output as a list of [value, keys] pairs.

Z   ɗ@/    With the keys on the right and the values on the left:
  ż        Zip
 Q         the unique values with
   ¹ƙ      the keys grouped by value, in order of the value's first appearance.

Nibbles, 6 bytes


Attempt This Online!

Takes and outputs a list of pairs.

.  Map
=~  group by
$    [input]
@    [second element]
~   pair
/    fold
.     map
$      [the group]
@      [second element]
$     [value]
.    map
      [the group]
      [first element]

5 bytes if we allow the output to be in the format [(values, key)] rather than [(key, values)]:


Attempt This Online!


Uiua, 11 bytes


Try it!

          ⍉  # transpose
        ⍘⊟   # uncouple
       ,     # over
      ⊛      # classify
    ⊕□       # group by box
   :         # flip
  ⊝          # deduplicate
∵⊂           # zip

Perl, 36 bytes

This is an anonymous function which takes a hash (not hash reference) as an argument, and returns a hash (not a hash reference) as its result. (A "hash" is Perl's name for a dictionary.) Although the language has dictionaries, it doesn't have sets; thus, for the values of the inverse dictionary (which are logically sets), I used the common Perl representation of a set as a hash, in which the keys are the set elements and the values are irrelevant.

Here's the program itself:


Here's how I tested it:

use Data::Dumper;
$f = sub{my%t;$t{+pop}{+pop}++while@_;%t};
my %test = qw/sky blue sea blue grass green/;
print Dumper({&$f(%test)});

The dump of the resulting hash is:

$VAR1 = {
          'blue' => {
                      'sky' => 1,
                      'sea' => 1
          'green' => {
                       'grass' => 1

which is the expected value.


Haskell, 55 bytes

foldl(\l(k,v)->maybe(v,[k])((,)v.(k:))(lookup v l):l)[]

This uses the good old association list as the data structure, which means that the output list may contain multiple elements with the same key, where only the first one is valid. However, I exploit the fact that the keys in the input list are all distinct.

Usage example:

*Main> foldl(\l(k,v)->maybe(v,[k])((,)v.(k:))(lookup v l):l)[] [("Clyde","blue"),("Sarah","blue"),("Fred","green")]

How it works:

foldl(   )[]                    -- starting with the empty list, reduce the
                                -- input list
    \l (k,v)->                  -- with via a lambda function that takes a list l
                                -- (the output list so far) and a key-value-pair
                                -- (k,v) from the input list and returns the next
                                -- version of the output list, which is made by:
                          :l    -- prepend to the existing list 
      maybe   (lookup v l)      -- if v is already a key in the output
           (,)v.(k:)            --     prepend k to the list for v
                                --     (this leaves the current pair in places and
                                --     adds the updated version to the front)
         (v,[k])                -- else a new pair with v and k flipped
                                --     and k put into a singleton list

Racket 208 bytes

(let p((l2(remove-duplicates(map(λ(x)(list-ref x 1))ll)))(ol'()))(cond[(empty? l2)(reverse ol)][ 
(p(rest l2)(cons(cons(first l2)(for/list((i ll)#:when(equal?(first l2)(list-ref i 1)))(list-ref i 0)))ol))]))


(define (f ll)
  (define l2 (remove-duplicates (map (λ (x) (list-ref x 1)) ll)))     
  (let loop ((l2 l2)
             (ol '()))
      [(empty? l2) (reverse ol)]
       (define tl (for/list ((i ll) #:when (equal? (first l2) (list-ref i 1)))
                    (list-ref i 0)))
       (loop (rest l2) (cons (cons (first l2) tl) ol))


(f '[("Clyde" "blue") ("Sarah" "blue") ("Fred" "green")])


'(("blue" "Clyde" "Sarah") ("green" "Fred"))

Groovy, 56 53 bytes



({m=[:];it.each{k,v->if(!m."$v"){x=m."$v"=[]};x<<k};m})(["Clyde": "blue", "Sarah": "blue", "Fred": "green"])


[blue:[Clyde, Sarah], green:[Fred]]

Java 7, 211 205 bytes


Map<String,List<String>>i(Map<String,String>m){Map<String,List<String>>r=new HashMap<>();for(String k:m.keySet()){String s=m.get(k);if(r.get(s)==null)r.put(s, new ArrayList<>());r.get(s).add(k);}return r;}


public static Map<String, List<String>> i(Map<String, String> m)
    Map<String, List<String>> r = new HashMap<>();
    for (String k : m.keySet())
        String s = m.get(k);
        if (r.get(s) == null)
            r.put(s, new ArrayList<>());
    return r;

Test it online!

Java ... the worst golfing language.


R, 79 69 bytes


R does not have a dictionary by default but the closest approximation to a dictionary is an object of class list. It's basically a generic vector allowing for multiple data types where each value (can basically be any R-object) is allowed to have a name/key.


A list with keys/names can be created as e.g.:

l <- list(Clyde="blue", Sarah="blue", Fred="green")

Which if printed returns:

[1] "blue"

[1] "blue"

[1] "green"

Calling the function now returns:

[1] "Clyde" "Sarah"

[1] "Fred"

Go, 107 bytes

type S=string
func f(m map[S]S)map[S][]S{O:=make(map[S][]S)
for k,v:=range m{O[v]=append(O[v],k)}
return O}

Attempt This Online!


Raku, 28 bytes

{push my Array%: .antipairs}

Try it online!

Raku hashes have an antipairs method that returns a list of the value-key pairs, and a push method that adds any number of key-value pairs, accumulating values associated with duplicated keys into arrays. So this answer could almost be just:

{push {}: .antipairs}

...but unfortunately the push method doesn't create an array value unless there actually is a duplicated key. In the provided example, it would associate the key "green" with the string "Fred", not the array ["Fred"]. So I address that by declaring that the anonymous returned hash has values of type Array.


Scala 3, 47 bytes


Attempt This Online!


Your Answer

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

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