class_docstr: An operand for shuffle execution which partitions data by the value in each record’s partition key, and
  send the partitioned data from all mappers to all reducers.
class_docstr_tok: ["An","operand","for","shuffle","execution","which","partitions","data","by","the","value","in","each","record","\u2019","s","partition","key",",","and","send","the","partitioned","data","from","all","mappers","to","all","reducers","."]
code: def iter_mapper_keys(self, input_id=0):
      # key is mapper chunk key, index is mapper chunk index.
      input_chunk = self.inputs[input_id]
      if isinstance(input_chunk.op, ShuffleProxy):
          keys = [inp.key for inp in input_chunk.inputs]
      else:
          assert isinstance(
              input_chunk.op, FetchShuffle
          ), input_chunk.op
          if (
              input_chunk.op.shuffle_fetch_type
              == ShuffleFetchType.FETCH_BY_INDEX
          ):
              # For fetch shuffle by index, all shuffle block of same reducers are
              # identified by their index. chunk key are not needed any more.
              # so just mock key here.
              # keep this in sync with ray executor `execute_subtask`.
              return list(range(input_chunk.op.n_mappers))
          keys = input_chunk.op.source_keys
      return keys
  
file_path: mars/mars/core/operand/shuffle.py
imports: from .None import ShuffleFetchType, FetchShuffle
  from ...None import opcodes
  from ...serialization.serializables import Int32Field, StringField, TupleField, FieldTypes
  from .base import Operand, VirtualOperand, OperandStage
label_desc: Use image node_id 4 for calling the MapReduceOperand obj's underlying member method code with example usage: obj.iter_mapper_keys(input_id) and returns: keys, list