From 14f293923dcad680aa9b3c4c72cb636a5bd556d5 Mon Sep 17 00:00:00 2001 From: Petre Mierlutiu Date: Sun, 21 Dec 2025 21:53:51 +0200 Subject: [PATCH 1/2] rna-transcription approach: a few improvements - Renamed `chr` to `char` in the snippets because `chr` is a built-in function and although shadowing it in this case may not be a problem, it is still a bad practice when it can be avoided. - The dictionary-join approach mentions list comprehensions, but instead it uses a generator expression. Replaced this in the explanation and expanded to give the list comprehension based implementation along with a brief comparison. - The overview mentions one approach is four times faster. In a brief comparison, it varies from 2.5x for a very short string and up to 60x faster for a 10^6 long one. Probably not worth going into the details, but 4x is just innacurate. --- .../.approaches/dictionary-join/content.md | 24 +++++++++++++++---- .../.approaches/dictionary-join/snippet.txt | 2 +- .../.approaches/introduction.md | 4 ++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md b/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md index f3ec1f755f..8f690b9cb9 100644 --- a/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md +++ b/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md @@ -5,7 +5,7 @@ LOOKUP = {"G": "C", "C": "G", "T": "A", "A": "U"} def to_rna(dna_strand): - return ''.join(LOOKUP[chr] for chr in dna_strand) + return ''.join(LOOKUP[char] for char in dna_strand) ``` @@ -16,15 +16,31 @@ but the `LOOKUP` dictionary is defined with all uppercase letters, which is the It indicates that the value is not intended to be changed. In the `to_rna()` function, the [`join()`][join] method is called on an empty string, -and is passed the list created from a [list comprehension][list-comprehension]. +and is passed the list created from a [generator expression][generator-expression]. -The list comprehension iterates each character in the input, +The generator expression iterates each character in the input, looks up the DNA character in the look-up dictionary, and outputs its matching RNA character as an element in the list. -The `join()` method collects the list of RNA characters back into a string. +The `join()` method collects the RNA characters back into a string. Since an empty string is the separator for the `join()`, there are no spaces between the RNA characters in the string. +A generator expression is similar to a [list comprehension][list-comprehension], but instead of creating a list, it returns a generator, and iterating that generator yields the elements on the fly. + +A variant that uses a list comprehension is almost identical, but note the additional square brackets inside the `join()`: + +```python +LOOKUP = {"G": "C", "C": "G", "T": "A", "A": "U"} + + +def to_rna(dna_strand): + return ''.join([LOOKUP[char] for char in dna_strand]) +``` + +For a relatively small number of elements, using lists is fine and is usually even faster, but as the size of the data increases, the memory consumption increases and performance decreases. See also [this discussion][list-comprehension-choose-generator-expression] regarding when to choose one over the other. + [dictionaries]: https://docs.python.org/3/tutorial/datastructures.html?#dictionaries [const]: https://realpython.com/python-constants/ [join]: https://docs.python.org/3/library/stdtypes.html?#str.join [list-comprehension]: https://realpython.com/list-comprehension-python/#using-list-comprehensions +[list-comprehension-choose-generator-expression]: https://realpython.com/list-comprehension-python/#choose-generators-for-large-datasets +[generator-expression]: https://realpython.com/introduction-to-python-generators/#building-generators-with-generator-expressions diff --git a/exercises/practice/rna-transcription/.approaches/dictionary-join/snippet.txt b/exercises/practice/rna-transcription/.approaches/dictionary-join/snippet.txt index 558bf98140..3d5da442fb 100644 --- a/exercises/practice/rna-transcription/.approaches/dictionary-join/snippet.txt +++ b/exercises/practice/rna-transcription/.approaches/dictionary-join/snippet.txt @@ -2,4 +2,4 @@ LOOKUP = {"G": "C", "C": "G", "T": "A", "A": "U"} def to_rna(dna_strand): - return ''.join(LOOKUP[chr] for chr in dna_strand) + return ''.join(LOOKUP[char] for char in dna_strand) diff --git a/exercises/practice/rna-transcription/.approaches/introduction.md b/exercises/practice/rna-transcription/.approaches/introduction.md index ca2d74a109..5f5f1c0be2 100644 --- a/exercises/practice/rna-transcription/.approaches/introduction.md +++ b/exercises/practice/rna-transcription/.approaches/introduction.md @@ -30,7 +30,7 @@ LOOKUP = {"G": "C", "C": "G", "T": "A", "A": "U"} def to_rna(dna_strand): - return ''.join(LOOKUP[chr] for chr in dna_strand) + return ''.join(LOOKUP[char] for char in dna_strand) ``` @@ -38,7 +38,7 @@ For more information, check the [dictionary look-up with `join()` approach][appr ## Which approach to use? -The `translate()` with `maketrans()` approach benchmarked over four times faster than the dictionary look-up with `join()` approach. +The `translate()` with `maketrans()` approach benchmarked many times faster than the dictionary look-up with `join()` approach. [ASCII]: https://www.asciitable.com/ [approach-translate-maketrans]: https://exercism.org/tracks/python/exercises/rna-transcription/approaches/translate-maketrans From 2e8a4e47dac3b3cda7d1b3a37edf3f58938d5e1e Mon Sep 17 00:00:00 2001 From: PetreM Date: Sun, 21 Dec 2025 23:26:54 +0200 Subject: [PATCH 2/2] Update exercises/practice/rna-transcription/.approaches/dictionary-join/content.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: AndrĂ¡s B Nagy <20251272+BNAndras@users.noreply.github.com> --- .../rna-transcription/.approaches/dictionary-join/content.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md b/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md index 8f690b9cb9..d2fd596ea2 100644 --- a/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md +++ b/exercises/practice/rna-transcription/.approaches/dictionary-join/content.md @@ -36,7 +36,8 @@ def to_rna(dna_strand): return ''.join([LOOKUP[char] for char in dna_strand]) ``` -For a relatively small number of elements, using lists is fine and is usually even faster, but as the size of the data increases, the memory consumption increases and performance decreases. See also [this discussion][list-comprehension-choose-generator-expression] regarding when to choose one over the other. +For a relatively small number of elements, using lists is fine and is usually even faster, but as the size of the data increases, the memory consumption increases and performance decreases. +See also [this discussion][list-comprehension-choose-generator-expression] regarding when to choose one over the other. [dictionaries]: https://docs.python.org/3/tutorial/datastructures.html?#dictionaries [const]: https://realpython.com/python-constants/