code: def _next_hyperparam(param_grid):
      """
      Iterator that gets the next parameter combination from a dictionary containing lists of parameters.
  
      The parameter combinations are deterministic and go over all possible combinations present in the parameter grid.
  
      Parameters
      ----------
      param_grid: dict
          Parameter configurations.
          Example::
              param_grid = {"k": [50, 100], "eta": [1, 2, 3]}
  
      Returns
      -------
      params: iterator
          One particular combination of parameters.
  
      """
      param_history = ParamHistory()
  
      # Flatten nested dictionaries so we can apply itertools.product to get all
      # possible parameter combinations
      flattened_param_grid = _flatten_nested_keys(param_grid)
  
      for values in product(*flattened_param_grid.values()):
          # Get one single parameter combination as a flattened dictionary
          param = dict(zip(flattened_param_grid.keys(), values))
  
          # Only yield unique parameter combinations
          if param in param_history:
              continue
          else:
              param_history.add(param)
              # Yields nested configuration (unflattened) without useless
              # parameters
              yield _unflatten_nested_keys(param)
  
imports: import logging
  from collections.abc import Iterable
  from itertools import islice, product
  import numpy
  import pandas
  from tqdm import tqdm
  from ..evaluation import hits_at_n_score, mr_score, mrr_score
label_desc: Use image node_id 6 for calling a global function with example usage: _next_hyperparam(param_grid) without return types