code: def _group_measurements(
      mps: List[
          Union[SampleMeasurement, ClassicalShadowMP, ShadowExpvalMP]
      ]
  ):
      """
      Group the measurements such that:
        - measurements with pauli observables pairwise-commute in each group
        - measurements with observables that are not pauli words are all in different groups
        - measurements without observables are all in the same group
        - classical shadow measurements are all in different groups
      """
      if len(mps) == 1:
          return [mps], [[0]]
  
      # measurements with pauli-word observables
      mp_pauli_obs = []
  
      # measurements with non pauli-word observables
      mp_other_obs = []
      mp_other_obs_indices = []
  
      # measurements with no observables
      mp_no_obs = []
      mp_no_obs_indices = []
  
      for i, mp in enumerate(mps):
          if isinstance(mp, (ClassicalShadowMP, ShadowExpvalMP)):
              mp_other_obs.append([mp])
              mp_other_obs_indices.append([i])
          elif mp.obs is None:
              mp_no_obs.append(mp)
              mp_no_obs_indices.append(i)
          elif isinstance(mp.obs, (Sum, Hamiltonian, SProd, Prod)):
              # Sum, Hamiltonian, SProd, and Prod are treated as valid Pauli words, but
              # aren't accepted in qml.pauli.group_observables
              mp_other_obs.append([mp])
              mp_other_obs_indices.append([i])
          elif qml.pauli.is_pauli_word(mp.obs):
              mp_pauli_obs.append((i, mp))
          else:
              mp_other_obs.append([mp])
              mp_other_obs_indices.append([i])
  
      if mp_pauli_obs:
          i_to_pauli_mp = dict(mp_pauli_obs)
          ob_groups, group_indices = qml.pauli.group_observables(
              [mp.obs for mp in i_to_pauli_mp.values()],
              list(i_to_pauli_mp.keys()),
          )
  
          mp_pauli_groups = []
          for group, indices in zip(ob_groups, group_indices):
              mp_group = [
                  i_to_pauli_mp[i].__class__(obs=ob)
                  for ob, i in zip(group, indices)
              ]
              mp_pauli_groups.append(mp_group)
      else:
          mp_pauli_groups, group_indices = [], []
  
      mp_no_obs_indices = [mp_no_obs_indices] if mp_no_obs else []
      mp_no_obs = [mp_no_obs] if mp_no_obs else []
  
      all_mp_groups = mp_pauli_groups + mp_no_obs + mp_other_obs
      all_indices = (
          group_indices + mp_no_obs_indices + mp_other_obs_indices
      )
  
      return all_mp_groups, all_indices
  
file_path: pennylane/pennylane/devices/qubit/sampling.py
imports: from typing import List, Union, Tuple
  import numpy
  import pennylane
  from pennylane.ops import Sum, Hamiltonian, SProd, Prod
  from pennylane.measurements import SampleMeasurement, Shots, ExpectationMP, ClassicalShadowMP, ShadowExpvalMP, CountsMP
  from pennylane.typing import TensorLike
  from .apply_operation import apply_operation
  from .measure import flatten_state
label_desc: Use image node_id 1 for calling a global function with example usage: _group_measurements(mps) and returns: all_mp_groups,  all_indices, list,  list