class_docstr: This represents the cartesian product of arbitrary :class:`Discrete` spaces.
  
  It is useful to represent game controllers or keyboards where each key can be represented as a discrete action space.
  
  Note:
      Some environment wrappers assume a value of 0 always represents the NOOP action.
  
  e.g. Nintendo Game Controller - Can be conceptualized as 3 discrete action spaces:
  
  1. Arrow Keys: Discrete 5  - NOOP[0], UP[1], RIGHT[2], DOWN[3], LEFT[4]  - params: min: 0, max: 4
  2. Button A:   Discrete 2  - NOOP[0], Pressed[1] - params: min: 0, max: 1
  3. Button B:   Discrete 2  - NOOP[0], Pressed[1] - params: min: 0, max: 1
  
  It can be initialized as ``MultiDiscrete([ 5, 2, 2 ])`` such that a sample might be ``array([3, 1, 0])``.
  
  Although this feature is rarely used, :class:`MultiDiscrete` spaces may also have several axes
  if ``nvec`` has several axes:
  
  Example::
  
      >> d = MultiDiscrete(np.array([[1, 2], [3, 4]]))
      >> d.sample()
      array([[0, 0],
             [2, 3]])
class_docstr_tok: ["This","represents","the","cartesian","product","of","arbitrary",":","class",":","`","Discrete","`","spaces",".","It","is","useful","to","represent","game","controllers","or","keyboards","where","each","key","can","be","represented","as","a","discrete","action","space",".","Note",":","Some","environment","wrappers","assume","a","value","of","0","always","represents","the","NOOP","action",".","e.g",".","Nintendo","Game","Controller","-","Can","be","conceptualized","as","3","discrete","action","spaces",":","1",".","Arrow","Keys",":","Discrete","5","-","NOOP","[","0","]",",","UP","[","1","]",",","RIGHT","[","2","]",",","DOWN","[","3","]",",","LEFT","[","4","]","-","params",":","min",":","0",",","max",":","4","2",".","Button","A",":","Discrete","2","-","NOOP","[","0","]",",","Pressed","[","1","]","-","params",":","min",":","0",",","max",":","1","3",".","Button","B",":","Discrete","2","-","NOOP","[","0","]",",","Pressed","[","1","]","-","params",":","min",":","0",",","max",":","1","It","can","be","initialized","as","``","MultiDiscrete","(","[","5",",","2",",","2","]",")","``","such","that","a","sample","might","be","``","array","(","[","3",",","1",",","0","]",")","``",".","Although","this","feature","is","rarely","used",",",":","class",":","`","MultiDiscrete","`","spaces","may","also","have","several","axes","if","``","nvec","``","has","several","axes",":","Example",":",":",">",">","d","=","MultiDiscrete","(","np.array","(","[","[","1",",","2","]",",","[","3",",","4","]","]",")",")",">",">","d.sample","(",")","array","(","[","[","0",",","0","]",",","[","2",",","3","]","]",")"]
docstr: Extract a subspace from this ``MultiDiscrete`` space.
docstr_tok: ["Extract","a","subspace","from","this","``","MultiDiscrete","``","space","."]
code: def __getitem__(self, index):
      """Extract a subspace from this ``MultiDiscrete`` space."""
      nvec = self.nvec[index]
      if nvec.ndim == 0:
          subspace = Discrete(nvec)
      else:
          subspace = MultiDiscrete(nvec, self.dtype)  # type: ignore
  
      # you don't need to deepcopy as np random generator call replaces the state not the data
      subspace.np_random.bit_generator.state = (
          self.np_random.bit_generator.state
      )
  
      return subspace
  
file_path: gym/gym/spaces/multi_discrete.py
imports: from typing import Iterable, List, Optional, Sequence, Tuple, Union
  import numpy
  from gym import logger
  from gym.spaces.discrete import Discrete
  from gym.spaces.space import Space
label_desc: Use image node_id 9 for calling the MultiDiscrete obj's underlying member method code with example usage: obj.__getitem__(index) and returns: subspace