class_docstr: Layer to flatten the example list.
  
  This layer flattens the batch_size dimension and the list_size dimension for
  the `example_features` and expands list_size times for the `context_features`.
  
  Example usage:
  
  ```python
  context_features = {'context_feature_1': [[1], [0]]}
  example_features = {'example_feature_1':
                      [[[1], [0], [-1]], [[0], [1], [0]]]}
  mask = [[True, True, False], [True, False, False]]
  flattened_context_features, flattened_example_features = FlattenList()(
      inputs=(context_features, example_features, mask))
  ```
  That is, there are two valid examples in the first query and one
  valid example in the second query. Then
  
  ```python
  flattened_context_features = {'context_feature_1':
                                [[1], [1], [1], [0], [0], [0]]}
  flattened_example_features = {'example_feature_1':
                                [[1], [0], [1], [0], [0], [0]]}
  ```
  `context_feature_1` is repeated by list_size=3 times. `example_feature_1` is
  flattened and padded with the invalid terms replaced by valid terms in each
  query in a circular way.
docstr: Call FlattenList layer to flatten context_features and example_features.
  
  Args:
    inputs: A tuple of (context_features, example_features, list_mask), which
      are described below:
    * `context_features`: A map of context features to 2D tensors of shape
      [batch_size, feature_dim].
    * `example_features`: A map of example features to 3D tensors of shape
      [batch_size, list_size, feature_dim].
    * `list_mask`: A Tensor of shape [batch_size, list_size] to mask out the
      invalid examples.
  
  Returns:
    A tuple of (flattened_context_features, flattened_example_fatures) where
    the former is a dict of context features to 2D tensors of shape
    [batch_size * list_size, feature_dim] and the latter is a dict of example
    features to 2D tensors of shape [batch_size * list_size, feature_dim].
  
  Raises:
    ValueError: If `example_features` is empty dict or None.
docstr_tok: ["Call","FlattenList","layer","to","flatten","context_features","and","example_features",".","Args",":","inputs",":","A","tuple","of","(","context_features",",","example_features",",","list_mask",")",",","which","are","described","below",":","*","`","context_features","`",":","A","map","of","context","features","to","2D","tensors","of","shape","[","batch_size",",","feature_dim","]",".","*","`","example_features","`",":","A","map","of","example","features","to","3D","tensors","of","shape","[","batch_size",",","list_size",",","feature_dim","]",".","*","`","list_mask","`",":","A","Tensor","of","shape","[","batch_size",",","list_size","]","to","mask","out","the","invalid","examples",".","Returns",":","A","tuple","of","(","flattened_context_features",",","flattened_example_fatures",")","where","the","former","is","a","dict","of","context","features","to","2D","tensors","of","shape","[","batch_size","*","list_size",",","feature_dim","]","and","the","latter","is","a","dict","of","example","features","to","2D","tensors","of","shape","[","batch_size","*","list_size",",","feature_dim","]",".","Raises",":","ValueError",":","If","`","example_features","`","is","empty","dict","or","None","."]
code: def call(
      self,
      inputs: Tuple[
          Dict[str, tf.Tensor], Dict[str, tf.Tensor], tf.Tensor
      ],
  ) -> Tuple[Dict[str, tf.Tensor], Dict[str, tf.Tensor]]:
      """Call FlattenList layer to flatten context_features and example_features.
  
      Args:
        inputs: A tuple of (context_features, example_features, list_mask), which
          are described below:
        * `context_features`: A map of context features to 2D tensors of shape
          [batch_size, feature_dim].
        * `example_features`: A map of example features to 3D tensors of shape
          [batch_size, list_size, feature_dim].
        * `list_mask`: A Tensor of shape [batch_size, list_size] to mask out the
          invalid examples.
  
      Returns:
        A tuple of (flattened_context_features, flattened_example_fatures) where
        the former is a dict of context features to 2D tensors of shape
        [batch_size * list_size, feature_dim] and the latter is a dict of example
        features to 2D tensors of shape [batch_size * list_size, feature_dim].
  
      Raises:
        ValueError: If `example_features` is empty dict or None.
      """
      context_features, example_features, list_mask = inputs
      if not example_features:
          raise ValueError("Need a valid example feature.")
      batch_size = tf.shape(list_mask)[0]
      list_size = tf.shape(list_mask)[1]
      # Expand context features to be of [batch_size, list_size, ...].
      flattened_context_features = {}
      for name, tensor in context_features.items():
          expanded_tensor = tf.repeat(
              tf.expand_dims(tensor, axis=1),
              repeats=[list_size],
              axis=1,
          )
          flattened_context_features[name] = utils.reshape_first_ndims(
              expanded_tensor, 2, [batch_size * list_size]
          )
  
      nd_indices = None
      if self._circular_padding:
          nd_indices, _ = utils.padded_nd_indices(is_valid=list_mask)
  
      flattened_example_features = {}
      for name, tensor in example_features.items():
          if nd_indices is not None:
              # Replace invalid example features with valid ones.
              tensor = tf.gather_nd(tensor, nd_indices)
          flattened_example_features[name] = utils.reshape_first_ndims(
              tensor, 2, [batch_size * list_size]
          )
  
      return flattened_context_features, flattened_example_features
  
imports: import math
  from typing import Any, Callable, Dict, List, Optional, Tuple
  import tensorflow
  from tensorflow_ranking.python import utils
label_desc: Use image node_id 2 for calling the FlattenList obj's underlying member method code with example usage: obj.call(inputs) and returns: flattened_context_features,  flattened_example_features