From 2f6f48ae879b8beceefbf9dd706d2fb4b58706a6 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Fri, 17 May 2024 15:58:24 +0800 Subject: [PATCH 1/7] popitem Signed-off-by: jayzhan211 --- stdlib/src/collections/dict.mojo | 22 ++++++++++++++++++++++ stdlib/test/collections/test_dict.mojo | 16 ++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/stdlib/src/collections/dict.mojo b/stdlib/src/collections/dict.mojo index 9d348ecc04..b52237b44a 100644 --- a/stdlib/src/collections/dict.mojo +++ b/stdlib/src/collections/dict.mojo @@ -799,6 +799,28 @@ struct Dict[K: KeyElement, V: CollectionElement]( return default.value()[] raise "KeyError" + fn popitem(inout self) raises -> DictEntry[K, V]: + """Remove and return a (key, value) pair from the dictionary. Pairs are returned in LIFO order. + popitem() is useful to destructively iterate over a dictionary, as often used in set algorithms. + If the dictionary is empty, calling popitem() raises a KeyError. + + Args: None + + Returns: + Last dictionary item + + Raises: + "KeyError" if the dictionary is empty. + """ + + for item in reversed(self.items()): + var key = item[].key + var value = item[].value + _ = self.pop(key) + return DictEntry[K, V](key, value) + + raise "KeyError" + fn keys( self: Reference[Self, _, _] ) -> _DictKeyIter[K, V, self.is_mutable, self.lifetime]: diff --git a/stdlib/test/collections/test_dict.mojo b/stdlib/test/collections/test_dict.mojo index b51f0cb13b..0788e4add1 100644 --- a/stdlib/test/collections/test_dict.mojo +++ b/stdlib/test/collections/test_dict.mojo @@ -452,6 +452,7 @@ def test_dict(): test["test_dict_update_empty_new", test_dict_update_empty_new]() test["test_mojo_issue_1729", test_mojo_issue_1729]() test["test dict or", test_dict_or]() + test["test dict popteim", test_dict_popitem]() def test_taking_owned_kwargs_dict(owned kwargs: OwnedKwargsDict[Int]): @@ -512,6 +513,21 @@ def test_find_get(): assert_equal(some_dict.get("not_key", 0), 0) +def test_dict_popitem(): + var dict = Dict[String, Int]() + dict["a"] = 1 + dict["b"] = 2 + + var item = dict.popitem() + assert_equal(item.key, "b") + assert_equal(item.value, 2) + item = dict.popitem() + assert_equal(item.key, "a") + assert_equal(item.value, 1) + with assert_raises(contains="KeyError"): + _ = dict.popitem() + + fn test_clear() raises: var some_dict = Dict[String, Int]() some_dict["key"] = 1 From 93c6d6ae692c813499606a5914b4e346f15b12d4 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Fri, 17 May 2024 16:01:38 +0800 Subject: [PATCH 2/7] changelog Signed-off-by: jayzhan211 --- docs/changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index ed4b6d8330..fbd7dd380f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,6 +18,8 @@ what we publish. ### ⭐️ New +- `Dict` now support `popitem`, which remove and return the last dict item. ([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) + - Add a `sort` function for list of `ComparableCollectionElement`s. [PR #2609](https://github.com/modularml/mojo/pull/2609) by [@mzaks](https://github.com/mzaks) From 7c9fde787392d44a4d6acc58546cdc394bc31640 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Fri, 17 May 2024 16:45:56 +0800 Subject: [PATCH 3/7] pop outside iterator Signed-off-by: jayzhan211 --- stdlib/src/collections/dict.mojo | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/stdlib/src/collections/dict.mojo b/stdlib/src/collections/dict.mojo index b52237b44a..3b41527d7e 100644 --- a/stdlib/src/collections/dict.mojo +++ b/stdlib/src/collections/dict.mojo @@ -813,11 +813,17 @@ struct Dict[K: KeyElement, V: CollectionElement]( "KeyError" if the dictionary is empty. """ + var key = Optional[K](None) + var val = Optional[V](None) + for item in reversed(self.items()): - var key = item[].key - var value = item[].value - _ = self.pop(key) - return DictEntry[K, V](key, value) + key = Optional(item[].key) + val = Optional(item[].value) + break + + if key: + _ = self.pop(key.value()[]) + return DictEntry[K, V](key.value()[], val.value()[]) raise "KeyError" From 4d78e9eb4c987a3f042c5521ba97a2dcf0202119 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Thu, 23 May 2024 09:14:03 +0800 Subject: [PATCH 4/7] more descriptive err and changlog Signed-off-by: jayzhan211 --- docs/changelog.md | 2 +- stdlib/src/collections/dict.mojo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index fbd7dd380f..aa4dffcd89 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,7 +18,7 @@ what we publish. ### ⭐️ New -- `Dict` now support `popitem`, which remove and return the last dict item. ([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) +- `Dict` now support `popitem`, which removes and returns the last item in the `Dict`. ([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) - Add a `sort` function for list of `ComparableCollectionElement`s. [PR #2609](https://github.com/modularml/mojo/pull/2609) by diff --git a/stdlib/src/collections/dict.mojo b/stdlib/src/collections/dict.mojo index 3b41527d7e..acd0bfdaf4 100644 --- a/stdlib/src/collections/dict.mojo +++ b/stdlib/src/collections/dict.mojo @@ -825,7 +825,7 @@ struct Dict[K: KeyElement, V: CollectionElement]( _ = self.pop(key.value()[]) return DictEntry[K, V](key.value()[], val.value()[]) - raise "KeyError" + raise "KeyError: popitem(): dictionary is empty" fn keys( self: Reference[Self, _, _] From ddf61fef2b0f22f0505124d165a2e247f17e8370 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Thu, 23 May 2024 09:21:49 +0800 Subject: [PATCH 5/7] changelog shorten length Signed-off-by: jayzhan211 --- docs/changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index aa4dffcd89..fa366618da 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,7 +18,8 @@ what we publish. ### ⭐️ New -- `Dict` now support `popitem`, which removes and returns the last item in the `Dict`. ([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) +- `Dict` now support `popitem`, which removes and returns the last item in the `Dict`. +([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) - Add a `sort` function for list of `ComparableCollectionElement`s. [PR #2609](https://github.com/modularml/mojo/pull/2609) by From 2c448b92096b50166f65fa1d4550ff8b6eaeaec8 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Thu, 23 May 2024 09:22:55 +0800 Subject: [PATCH 6/7] changelog shorten length Signed-off-by: jayzhan211 --- docs/changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index fa366618da..b1bb46c5cc 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,7 +19,8 @@ what we publish. ### ⭐️ New - `Dict` now support `popitem`, which removes and returns the last item in the `Dict`. -([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) +([PR #2701](https://github.com/modularml/mojo/pull/2701) +by [@jayzhan211](https://github.com/jayzhan211)) - Add a `sort` function for list of `ComparableCollectionElement`s. [PR #2609](https://github.com/modularml/mojo/pull/2609) by From 13783793541eed1ce2c0e705ac3377f2c4f659f2 Mon Sep 17 00:00:00 2001 From: jayzhan211 Date: Thu, 23 May 2024 09:26:30 +0800 Subject: [PATCH 7/7] md lint Signed-off-by: jayzhan211 --- docs/changelog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index b1bb46c5cc..529d929a3e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,8 +18,8 @@ what we publish. ### ⭐️ New -- `Dict` now support `popitem`, which removes and returns the last item in the `Dict`. -([PR #2701](https://github.com/modularml/mojo/pull/2701) +- `Dict` now support `popitem`, which removes and returns the last item in the `Dict`. +([PR #2701](https://github.com/modularml/mojo/pull/2701) by [@jayzhan211](https://github.com/jayzhan211)) - Add a `sort` function for list of `ComparableCollectionElement`s.