code: def iter_output_data(
      chunk_graph: ChunkGraph, context: Dict[str, Any]
  ) -> Iterator[Tuple[str, Any, bool]]:
      """An iterator yield (output chunk key, output data, is shuffle)."""
      data_keys = set()
      for result_chunk in chunk_graph.result_chunks:
          # skip virtual operands for result chunks
          if isinstance(result_chunk.op, VirtualOperand):
              continue
          key = result_chunk.key
          if key in context:
              # non shuffle op
              data = context[key]
              # update meta
              if not isinstance(data, tuple):
                  result_chunk.params = (
                      result_chunk.get_params_from_data(data)
                  )
              # check key after update meta
              if key in data_keys:
                  continue
              yield key, data, False
              data_keys.add(key)
          else:
              assert isinstance(result_chunk.op, MapReduceOperand)
              keys = get_mapper_data_keys(key, context)
              for key in keys:
                  if key in data_keys:
                      continue
                  # shuffle op
                  data = context[key]
                  yield key, data, True
                  data_keys.add(key)
  
imports: from typing import Any, Dict, List, Iterator, Tuple
  from ...core import ChunkGraph
  from ...core.operand import Fetch, FetchShuffle, MapReduceOperand, VirtualOperand
  from .core import Subtask
label_desc: Use image node_id 3 for calling a global function with example usage: iter_output_data(chunk_graph, context) without return types