code: def shadow_expval(H, k=1, seed=None):
      r"""Compute expectation values using classical shadows in a differentiable manner.
  
      The canonical way of computing expectation values is to simply average the expectation values for each local snapshot, :math:`\langle O \rangle = \sum_t \text{tr}(\rho^{(t)}O) / T`.
      This corresponds to the case ``k=1``. In the original work, `2002.08953 <https://arxiv.org/abs/2002.08953>`_, it has been proposed to split the ``T`` measurements into ``k`` equal
      parts to compute the median of means. For the case of Pauli measurements and Pauli observables, there is no advantage expected from setting ``k>1``.
  
      Args:
          H (Union[Iterable[Operator], Operator]): Observable or
              iterable of observables to compute the expectation value over.
          k (int): Number of equal parts to split the shadow's measurements to compute the median of means. ``k=1`` (default) corresponds to simply taking the mean over all measurements.
          seed (Union[None, int]):  Seed used to randomly sample Pauli measurements during the
              classical shadows protocol. If None, a random seed will be generated. If a tape with
              a ``shadow_expval`` measurement is copied, the seed will also be copied.
              Different seeds are still generated for different constructed tapes.
  
      Returns:
          ShadowExpvalMP: Measurement process instance
  
      .. note::
  
          This measurement uses the measurement :func:`~.pennylane.classical_shadow` and the class :class:`~.pennylane.ClassicalShadow` for post-processing
          internally to compute expectation values. In order to compute correct gradients using PennyLane's automatic differentiation,
          you need to use this measurement.
  
      **Example**
  
      .. code-block:: python3
  
          H = qml.Hamiltonian([1., 1.], [qml.PauliZ(0) @ qml.PauliZ(1), qml.PauliX(0) @ qml.PauliX(1)])
  
          dev = qml.device("default.qubit", wires=range(2), shots=10000)
          @qml.qnode(dev)
          def circuit(x, obs):
              qml.Hadamard(0)
              qml.CNOT((0,1))
              qml.RX(x, wires=0)
              return qml.shadow_expval(obs)
  
          x = np.array(0.5, requires_grad=True)
  
      We can compute the expectation value of H as well as its gradient in the usual way.
  
      >>> circuit(x, H)
      array(1.8774)
      >>> qml.grad(circuit)(x, H)
      -0.44999999999999984
  
      In ``shadow_expval``, we can pass a list of observables. Note that each qnode execution internally performs one quantum measurement, so be sure
      to include all observables that you want to estimate from a single measurement in the same execution.
  
      >>> Hs = [H, qml.PauliX(0), qml.PauliY(0), qml.PauliZ(0)]
      >>> circuit(x, Hs)
      array([ 1.881 , -0.0312, -0.0027, -0.0087])
      >>> qml.jacobian(circuit)(x, Hs)
      array([-0.4518,  0.0174, -0.0216, -0.0063])
      """
      seed = seed or np.random.randint(2**30)
      return ShadowExpvalMP(H=H, seed=seed, k=k)
  
imports: import copy
  from collections.abc import Iterable
  from typing import Optional, Union, Sequence
  from string import ascii_letters
  import numpy
  import pennylane
  from pennylane.operation import Operator
  from pennylane.wires import Wires
  from .measurements import MeasurementShapeError, MeasurementTransform, Shadow, ShadowExpval
label_desc: Use image node_id 1 for calling a global function with example usage: shadow_expval(H, k, seed) and returns: ShadowExpvalMP