We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Improve MetricLambda implementation
User can get the following output in the `state.metrics`:
```
{'accuracy': 0.37127896829244644,
 'error': 0.6287210317075536,
 'error[0]': -0.6287210317075536,
 'error[0][0]': 0.37127896829244644,
```
when launch the below code:
```python
accuracy_metric = Accuracy()
error_metric = (accuracy_metric - 1.0) * (-1.0)

metrics = {
    "accuracy": accuracy_metric,
    "error": error_metric,
}

validator = create_supervised_evaluator(model, metrics=metrics)
validator.run(val_loader, max_epochs=1)
print(validator.state.metrics)
```

This is due to 

https://github.com/pytorch/ignite/blob/d9820451da779e0d0c393804db381e5483240b1c/ignite/metrics/metrics_lambda.py#L50-L54

and 

https://github.com/pytorch/ignite/blob/d9820451da779e0d0c393804db381e5483240b1c/ignite/metrics/metric.py#L68

IMO, user is not interested of this internal info used to compute `error_metric`. We can add some special characters to ignore the result of compute when insert to `engine.state.metrics[name]`.

cc @zasdfgbnm 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ignite/metrics/metrics_lambda.py`
Content:
```
1 from ignite.metrics.metric import Metric
2 
3 
4 class MetricsLambda(Metric):
5     """
6     Apply a function to other metrics to obtain a new metric.
7     The result of the new metric is defined to be the result
8     of applying the function to the result of argument metrics.
9 
10     When update, this metric does not recursively update the metrics
11     it depends on. When reset, all its dependency metrics would be
12     resetted. When attach, all its dependencies would be automatically
13     attached.
14 
15     Arguments:
16         f (callable): the function that defines the computation
17         args (sequence): Sequence of other metrics or something
18             else that will be fed to ``f`` as arguments.
19 
20     Examples:
21         >>> precision = Precision(average=False)
22         >>> recall = Recall(average=False)
23         >>> def Fbeta(r, p, beta):
24         >>>     return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r)).item()
25         >>> F1 = MetricsLambda(Fbeta, recall, precision, 1)
26         >>> F2 = MetricsLambda(Fbeta, recall, precision, 2)
27         >>> F3 = MetricsLambda(Fbeta, recall, precision, 3)
28         >>> F4 = MetricsLambda(Fbeta, recall, precision, 4)
29     """
30     def __init__(self, f, *args):
31         self.function = f
32         self.args = args
33         super(MetricsLambda, self).__init__()
34 
35     def reset(self):
36         for i in self.args:
37             if isinstance(i, Metric):
38                 i.reset()
39 
40     def update(self, output):
41         # NB: this method does not recursively update dependency metrics,
42         # which might cause duplicate update issue. To update this metric,
43         # users should manually update its dependencies.
44         pass
45 
46     def compute(self):
47         materialized = [i.compute() if isinstance(i, Metric) else i for i in self.args]
48         return self.function(*materialized)
49 
50     def attach(self, engine, name):
51         # recursively attach all its dependencies
52         for index, metric in enumerate(self.args):
53             if isinstance(metric, Metric):
54                 metric.attach(engine, name + '[{}]'.format(index))
55         super(MetricsLambda, self).attach(engine, name)
56
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ignite/metrics/metrics_lambda.py b/ignite/metrics/metrics_lambda.py
--- a/ignite/metrics/metrics_lambda.py
+++ b/ignite/metrics/metrics_lambda.py
@@ -1,4 +1,5 @@
 from ignite.metrics.metric import Metric
+from ignite.engine import Events
 
 
 class MetricsLambda(Metric):
@@ -12,20 +13,25 @@
     resetted. When attach, all its dependencies would be automatically
     attached.
 
-    Arguments:
+    Args:
         f (callable): the function that defines the computation
         args (sequence): Sequence of other metrics or something
             else that will be fed to ``f`` as arguments.
 
-    Examples:
-        >>> precision = Precision(average=False)
-        >>> recall = Recall(average=False)
-        >>> def Fbeta(r, p, beta):
-        >>>     return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r)).item()
-        >>> F1 = MetricsLambda(Fbeta, recall, precision, 1)
-        >>> F2 = MetricsLambda(Fbeta, recall, precision, 2)
-        >>> F3 = MetricsLambda(Fbeta, recall, precision, 3)
-        >>> F4 = MetricsLambda(Fbeta, recall, precision, 4)
+    Example:
+
+    .. code-block:: python
+
+        precision = Precision(average=False)
+        recall = Recall(average=False)
+
+        def Fbeta(r, p, beta):
+            return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r + 1e-20)).item()
+
+        F1 = MetricsLambda(Fbeta, recall, precision, 1)
+        F2 = MetricsLambda(Fbeta, recall, precision, 2)
+        F3 = MetricsLambda(Fbeta, recall, precision, 3)
+        F4 = MetricsLambda(Fbeta, recall, precision, 4)
     """
     def __init__(self, f, *args):
         self.function = f
@@ -51,5 +57,8 @@
         # recursively attach all its dependencies
         for index, metric in enumerate(self.args):
             if isinstance(metric, Metric):
-                metric.attach(engine, name + '[{}]'.format(index))
+                if not engine.has_event_handler(metric.started, Events.EPOCH_STARTED):
+                    engine.add_event_handler(Events.EPOCH_STARTED, metric.started)
+                if not engine.has_event_handler(metric.iteration_completed, Events.ITERATION_COMPLETED):
+                    engine.add_event_handler(Events.ITERATION_COMPLETED, metric.iteration_completed)
         super(MetricsLambda, self).attach(engine, name)

{"golden_diff": "diff --git a/ignite/metrics/metrics_lambda.py b/ignite/metrics/metrics_lambda.py\n--- a/ignite/metrics/metrics_lambda.py\n+++ b/ignite/metrics/metrics_lambda.py\n@@ -1,4 +1,5 @@\n from ignite.metrics.metric import Metric\n+from ignite.engine import Events\n \n \n class MetricsLambda(Metric):\n@@ -12,20 +13,25 @@\n     resetted. When attach, all its dependencies would be automatically\n     attached.\n \n-    Arguments:\n+    Args:\n         f (callable): the function that defines the computation\n         args (sequence): Sequence of other metrics or something\n             else that will be fed to ``f`` as arguments.\n \n-    Examples:\n-        >>> precision = Precision(average=False)\n-        >>> recall = Recall(average=False)\n-        >>> def Fbeta(r, p, beta):\n-        >>>     return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r)).item()\n-        >>> F1 = MetricsLambda(Fbeta, recall, precision, 1)\n-        >>> F2 = MetricsLambda(Fbeta, recall, precision, 2)\n-        >>> F3 = MetricsLambda(Fbeta, recall, precision, 3)\n-        >>> F4 = MetricsLambda(Fbeta, recall, precision, 4)\n+    Example:\n+\n+    .. code-block:: python\n+\n+        precision = Precision(average=False)\n+        recall = Recall(average=False)\n+\n+        def Fbeta(r, p, beta):\n+            return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r + 1e-20)).item()\n+\n+        F1 = MetricsLambda(Fbeta, recall, precision, 1)\n+        F2 = MetricsLambda(Fbeta, recall, precision, 2)\n+        F3 = MetricsLambda(Fbeta, recall, precision, 3)\n+        F4 = MetricsLambda(Fbeta, recall, precision, 4)\n     \"\"\"\n     def __init__(self, f, *args):\n         self.function = f\n@@ -51,5 +57,8 @@\n         # recursively attach all its dependencies\n         for index, metric in enumerate(self.args):\n             if isinstance(metric, Metric):\n-                metric.attach(engine, name + '[{}]'.format(index))\n+                if not engine.has_event_handler(metric.started, Events.EPOCH_STARTED):\n+                    engine.add_event_handler(Events.EPOCH_STARTED, metric.started)\n+                if not engine.has_event_handler(metric.iteration_completed, Events.ITERATION_COMPLETED):\n+                    engine.add_event_handler(Events.ITERATION_COMPLETED, metric.iteration_completed)\n         super(MetricsLambda, self).attach(engine, name)\n", "issue": "Improve MetricLambda implementation\nUser can get the following output in the `state.metrics`:\r\n```\r\n{'accuracy': 0.37127896829244644,\r\n 'error': 0.6287210317075536,\r\n 'error[0]': -0.6287210317075536,\r\n 'error[0][0]': 0.37127896829244644,\r\n```\r\nwhen launch the below code:\r\n```python\r\naccuracy_metric = Accuracy()\r\nerror_metric = (accuracy_metric - 1.0) * (-1.0)\r\n\r\nmetrics = {\r\n    \"accuracy\": accuracy_metric,\r\n    \"error\": error_metric,\r\n}\r\n\r\nvalidator = create_supervised_evaluator(model, metrics=metrics)\r\nvalidator.run(val_loader, max_epochs=1)\r\nprint(validator.state.metrics)\r\n```\r\n\r\nThis is due to \r\n\r\nhttps://github.com/pytorch/ignite/blob/d9820451da779e0d0c393804db381e5483240b1c/ignite/metrics/metrics_lambda.py#L50-L54\r\n\r\nand \r\n\r\nhttps://github.com/pytorch/ignite/blob/d9820451da779e0d0c393804db381e5483240b1c/ignite/metrics/metric.py#L68\r\n\r\nIMO, user is not interested of this internal info used to compute `error_metric`. We can add some special characters to ignore the result of compute when insert to `engine.state.metrics[name]`.\r\n\r\ncc @zasdfgbnm \n", "before_files": [{"content": "from ignite.metrics.metric import Metric\n\n\nclass MetricsLambda(Metric):\n    \"\"\"\n    Apply a function to other metrics to obtain a new metric.\n    The result of the new metric is defined to be the result\n    of applying the function to the result of argument metrics.\n\n    When update, this metric does not recursively update the metrics\n    it depends on. When reset, all its dependency metrics would be\n    resetted. When attach, all its dependencies would be automatically\n    attached.\n\n    Arguments:\n        f (callable): the function that defines the computation\n        args (sequence): Sequence of other metrics or something\n            else that will be fed to ``f`` as arguments.\n\n    Examples:\n        >>> precision = Precision(average=False)\n        >>> recall = Recall(average=False)\n        >>> def Fbeta(r, p, beta):\n        >>>     return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r)).item()\n        >>> F1 = MetricsLambda(Fbeta, recall, precision, 1)\n        >>> F2 = MetricsLambda(Fbeta, recall, precision, 2)\n        >>> F3 = MetricsLambda(Fbeta, recall, precision, 3)\n        >>> F4 = MetricsLambda(Fbeta, recall, precision, 4)\n    \"\"\"\n    def __init__(self, f, *args):\n        self.function = f\n        self.args = args\n        super(MetricsLambda, self).__init__()\n\n    def reset(self):\n        for i in self.args:\n            if isinstance(i, Metric):\n                i.reset()\n\n    def update(self, output):\n        # NB: this method does not recursively update dependency metrics,\n        # which might cause duplicate update issue. To update this metric,\n        # users should manually update its dependencies.\n        pass\n\n    def compute(self):\n        materialized = [i.compute() if isinstance(i, Metric) else i for i in self.args]\n        return self.function(*materialized)\n\n    def attach(self, engine, name):\n        # recursively attach all its dependencies\n        for index, metric in enumerate(self.args):\n            if isinstance(metric, Metric):\n                metric.attach(engine, name + '[{}]'.format(index))\n        super(MetricsLambda, self).attach(engine, name)\n", "path": "ignite/metrics/metrics_lambda.py"}], "after_files": [{"content": "from ignite.metrics.metric import Metric\nfrom ignite.engine import Events\n\n\nclass MetricsLambda(Metric):\n    \"\"\"\n    Apply a function to other metrics to obtain a new metric.\n    The result of the new metric is defined to be the result\n    of applying the function to the result of argument metrics.\n\n    When update, this metric does not recursively update the metrics\n    it depends on. When reset, all its dependency metrics would be\n    resetted. When attach, all its dependencies would be automatically\n    attached.\n\n    Args:\n        f (callable): the function that defines the computation\n        args (sequence): Sequence of other metrics or something\n            else that will be fed to ``f`` as arguments.\n\n    Example:\n\n    .. code-block:: python\n\n        precision = Precision(average=False)\n        recall = Recall(average=False)\n\n        def Fbeta(r, p, beta):\n            return torch.mean((1 + beta ** 2) * p * r / (beta ** 2 * p + r + 1e-20)).item()\n\n        F1 = MetricsLambda(Fbeta, recall, precision, 1)\n        F2 = MetricsLambda(Fbeta, recall, precision, 2)\n        F3 = MetricsLambda(Fbeta, recall, precision, 3)\n        F4 = MetricsLambda(Fbeta, recall, precision, 4)\n    \"\"\"\n    def __init__(self, f, *args):\n        self.function = f\n        self.args = args\n        super(MetricsLambda, self).__init__()\n\n    def reset(self):\n        for i in self.args:\n            if isinstance(i, Metric):\n                i.reset()\n\n    def update(self, output):\n        # NB: this method does not recursively update dependency metrics,\n        # which might cause duplicate update issue. To update this metric,\n        # users should manually update its dependencies.\n        pass\n\n    def compute(self):\n        materialized = [i.compute() if isinstance(i, Metric) else i for i in self.args]\n        return self.function(*materialized)\n\n    def attach(self, engine, name):\n        # recursively attach all its dependencies\n        for index, metric in enumerate(self.args):\n            if isinstance(metric, Metric):\n                if not engine.has_event_handler(metric.started, Events.EPOCH_STARTED):\n                    engine.add_event_handler(Events.EPOCH_STARTED, metric.started)\n                if not engine.has_event_handler(metric.iteration_completed, Events.ITERATION_COMPLETED):\n                    engine.add_event_handler(Events.ITERATION_COMPLETED, metric.iteration_completed)\n        super(MetricsLambda, self).attach(engine, name)\n", "path": "ignite/metrics/metrics_lambda.py"}]}