diff --git a/IPython/core/completer.py b/IPython/core/completer.py
index fdbfc8b..804ae8f 100644
--- a/IPython/core/completer.py
+++ b/IPython/core/completer.py
@@ -753,7 +753,8 @@ def get__all__entries(obj):
     return [w for w in words if isinstance(w, str)]
 
 
-def match_dict_keys(keys: List[Union[str, bytes]], prefix: str, delims: str) -> Tuple[str, int, List[str]]:
+def match_dict_keys(keys: List[Union[str, bytes, Tuple[Union[str, bytes]]]], prefix: str, delims: str,
+                    prefix_tuple: Tuple[str, bytes]=()) -> Tuple[str, int, List[str]]:
     """Used by dict_key_matches, matching the prefix to a list of keys
 
     Parameters
@@ -761,9 +762,12 @@ def match_dict_keys(keys: List[Union[str, bytes]], prefix: str, delims: str) -> 
     keys:
         list of keys in dictionary currently being completed.
     prefix:
-        Part of the text already typed by the user. e.g. `mydict[b'fo`
+        Part of the text already typed by the user. E.g. `mydict[b'fo`
     delims:
         String of delimiters to consider when finding the current key.
+    prefix_tuple: optional
+        Part of the text already typed in multi-key index cases. E.g. for 
+        `mydict['foo', "bar", 'b`, this would be `('foo', 'bar')`.
 
     Returns
     =======
@@ -774,7 +778,23 @@ def match_dict_keys(keys: List[Union[str, bytes]], prefix: str, delims: str) -> 
     ``matches`` a list of replacement/completion
 
     """
-    keys = [k for k in keys if isinstance(k, (str, bytes))]
+    Nprefix = len(prefix_tuple)
+    def filter_by_prefix_tuple(key):
+        if len(key) < Nprefix:
+            return False
+        for k, pt in zip(key, prefix_tuple):
+            if k != pt:
+                return False
+        return True
+
+    new_keys = []
+    for k in keys:
+        if isinstance(k, (str, bytes)):
+            new_keys.append(k)
+        elif isinstance(k, tuple) and filter_by_prefix_tuple(k):
+            new_keys.append(k[Nprefix])
+
+    keys = new_keys
     if not prefix:
         return '', 0, [repr(k) for k in keys
                       if isinstance(k, (str, bytes))]
@@ -1641,6 +1661,7 @@ class IPCompleter(Completer):
             )
             \[   # open bracket
             \s*  # and optional whitespace
+            # Capture any number of str-like objects (e.g. "a", "b", 'c')
             ((?:[uUbB]?  # string prefix (r not handled)
                 (?:
                     '(?:[^']|(?<!\\)\\')*'
@@ -1670,10 +1691,11 @@ class IPCompleter(Completer):
             }
 
         match = regexps[self.greedy].search(self.text_until_cursor)
+
         if match is None:
             return []
 
-        expr, prefix = match.groups()
+        expr, prefix0, prefix = match.groups()
         try:
             obj = eval(expr, self.namespace)
         except Exception:
@@ -1685,7 +1707,13 @@ class IPCompleter(Completer):
         keys = self._get_keys(obj)
         if not keys:
             return keys
-        closing_quote, token_offset, matches = match_dict_keys(keys, prefix, self.splitter.delims)
+
+        if prefix0 != '':
+            tuple_prefix = eval(prefix0)
+        else:
+            tuple_prefix = tuple()
+
+        closing_quote, token_offset, matches = match_dict_keys(keys, tuple_prefix, prefix, self.splitter.delims)
         if not matches:
             return matches
 
@@ -1695,7 +1723,7 @@ class IPCompleter(Completer):
         # - the start of the completion
         text_start = len(self.text_until_cursor) - len(text)
         if prefix:
-            key_start = match.start(2)
+            key_start = match.start(3)
             completion_start = key_start + token_offset
         else:
             key_start = completion_start = match.end()
@@ -2097,7 +2125,7 @@ class IPCompleter(Completer):
 
         # Start with a clean slate of completions
         matches = []
-        
+
         # FIXME: we should extend our api to return a dict with completions for
         # different types of objects.  The rlcomplete() method could then
         # simply collapse the dict into a list for readline, but we'd have