Sick Gaming
[Tut] How to Use Python’s Join() on a List of Objects (Not Strings)? - Printable Version

+- Sick Gaming (https://www.sickgaming.net)
+-- Forum: Programming (https://www.sickgaming.net/forum-76.html)
+--- Forum: Python (https://www.sickgaming.net/forum-83.html)
+--- Thread: [Tut] How to Use Python’s Join() on a List of Objects (Not Strings)? (/thread-95739.html)



[Tut] How to Use Python’s Join() on a List of Objects (Not Strings)? - xSicKxBot - 06-17-2020

How to Use Python’s Join() on a List of Objects (Not Strings)?

<div><p class="has-background has-luminous-vivid-amber-background-color"><strong>The most Pythonic way to concatenate a list of objects is the expression <code>''.join(str(x) for x in lst)</code> that converts each object to a string using the built-in <code>str(...)</code> function in a generator expression. You can concatenate the resulting list of strings using the <code>join()</code> method on the empty string as a delimiter. The result is a single string value that’s the concatenation of the objects’ string representations.</strong></p>
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio">
<div class="wp-block-embed__wrapper">
<div class="ast-oembed-container"><iframe title="What's The Most Pythonic Way to Concatenate a List of Objects into a String?" width="1400" height="788" src="https://www.youtube.com/embed/_JDhMYSIDWI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
</div>
</figure>
<p>Writing Pythonic code is at the heart of being an effective coder—and if you choose the wrong ways of solving a problem, you’ll open yourself up for criticism and struggles throughout your <a href="https://blog.finxter.com/programming-your-intelligence/" target="_blank" rel="noreferrer noopener">programming career</a>. So, what’s the most Pythonic way of solving the following problem?</p>
<p><strong>Problem</strong>: Given a <a rel="noreferrer noopener" href="https://blog.finxter.com/python-lists/" target="_blank">list</a> of objects. How to <a rel="noreferrer noopener" href="https://blog.finxter.com/concatenate-lists-in-python/" target="_blank">concatenate </a>the string representations of those objects?</p>
<p><strong>Example</strong>: You have the following list of objects.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Obj: def __init__(self, val): self.val = val def __str__(self): return str(self.val) lst = [Obj(0), Obj(1), Obj(2), Obj(4)]</pre>
<p>You want to obtain the following result of concatenated string <a href="https://blog.finxter.com/python-join-list-of-unicode-strings/" target="_blank" rel="noreferrer noopener">representations </a>of the objects in the list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">0124</pre>
<p>Want to play? Run the following interactive code shell:</p>
<p> <iframe src="https://trinket.io/embed/python/0b30e74dbc" width="100%" height="600" frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe> </p>
<p><em><strong>Exercise</strong>: Run the interactive code snippet. Which method do you like most?</em></p>
<h2>Method 1: Join + List Comprehension + Str</h2>
<p>This method uses three Python features.</p>
<p>First, the <code>string.join(iterable)</code> method expects an <code>iterable</code> of strings as input and concatenates those using the <code>string</code> delimiter. <a rel="noreferrer noopener" href="https://blog.finxter.com/python-join-list/" target="_blank">You can read more about the<code> join()</code> function in our ultimate blog guide.</a></p>
<p>Second, list comprehension is the Pythonic way to create Python lists in a single line. You use the syntax <code>[expression + statement]</code>. </p>
<ul>
<li>In the <code>expression</code>, you define how each element should be modified before adding it into a new list. </li>
<li>In the <code>statement</code>, you define which elements to modify and add to the list in the first place. </li>
</ul>
<p><a rel="noreferrer noopener" href="https://blog.finxter.com/list-comprehension/" target="_blank">You can read more about list comprehension in the detailed Finxter guide on the topic.</a></p>
<p>Third, the <code>str(...)</code> function converts any Python object into a string representation. If you define your custom objects, you should overwrite the <code>__str__()</code> method to customize how exactly your objects are represented as strings.</p>
<p>Combining those three features results in the following simple solution to concatenate the string representations of a list of objects.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(''.join([str(x) for x in lst]))
# 0124</pre>
<p>But there’s a slight simplification lurking around. Read on to learn which!</p>
<h2>Method 2: Join + Generator Expression + Str</h2>
<p>The previous method has shown a quite effective way to concatenate the string representations of some objects using the <code>join()</code> function of Python strings. As the <code>join()</code> function expects a <a href="https://blog.finxter.com/python-list-to-string/" target="_blank" rel="noreferrer noopener">list of strings</a>, you need to convert all objects <code>x</code> into plain strings using the<code> str(x)</code> function. </p>
<figure class="wp-block-image size-large is-resized"><img src="https://blog.finxter.com/wp-content/uploads/2020/06/pythonjoinlistobject-1024x576.jpg" alt="Concatenate string representations of list of objects with join() function and generator expression." class="wp-image-9810" width="768" height="432" srcset="https://blog.finxter.com/wp-content/uploads/2020/06/pythonjoinlistobject-scaled.jpg 1024w, https://blog.finxter.com/wp-content/uploads/2020/06/pythonjoinlistobject-300x169.jpg 300w, https://blog.finxter.com/wp-content/uploads/2020/06/pythonjoinlistobject-768x432.jpg 768w" sizes="(max-width: 768px) 100vw, 768px" /></figure>
<p>However, there’s no need to create a separate list in which you store the string representations. Converting one <a href="https://blog.finxter.com/object-oriented-programming-terminology-cheat-sheet/" target="_blank" rel="noreferrer noopener">object </a>at a time is enough because the join function needs only an iterable as an input—and not necessarily a <a href="https://blog.finxter.com/python-list-methods-cheat-sheet-instant-pdf-download/" target="_blank" rel="noreferrer noopener">Python list</a>. <em>(All Python lists are iterables but not all iterables are Python lists.)</em></p>
<p>To free up the memory, you can use a <a href="https://blog.finxter.com/how-to-use-generator-expressions-in-python-dictionaries/" target="_blank" rel="noreferrer noopener">generator expression</a> (without the square brackets needed to create a list):</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(''.join(str(x) for x in lst))
# 0124</pre>
<p>In contrast to Method 1, this ensures that the original list does not exist in memory twice—once as a list of objects and once as a list of string represenations of those exact objects. Therefore, this method can be considered <a href="https://blog.finxter.com/whats-the-best-pep8-python-style-checker/" target="_blank" rel="noreferrer noopener">the most Pythonic</a> one.</p>
<h2>Method 3: Join + Generator Expression + Custom String Representation</h2>
<p>A slight modification of the previous version is to use your own custom string representation—rather than the one implemented by the <code>__str__</code> method.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(''.join(str(x.val) for x in lst))
# 0124</pre>
<p>This gives you some flexibility how you can represent each object for your specific application.</p>
<h2>Method 4: Join + Map + Lambda</h2>
<p>The <a rel="noreferrer noopener" href="https://blog.finxter.com/how-to-get-rid-of-pythons-map-function-with-list-comprehension/" target="_blank"><code>map()</code> function</a> transforms each tuple into a string value, and the <code>join()</code> method transforms the <a rel="noreferrer noopener" href="https://blog.finxter.com/python-join-list/" target="_blank">collection </a>of strings to a single string—using the given delimiter <code>'--'</code>. If you forget to transform each tuple into a string with the <code>map()</code> function, you’ll get a <code>TypeError</code> because the <code>join()</code> method expects a collection of strings.</p>
<p><a rel="noreferrer noopener" href="https://blog.finxter.com/a-simple-introduction-of-the-lambda-function-in-python/" target="_blank">Lambda functions</a> are anonymous functions that are not defined in the <a href="https://blog.finxter.com/python-namespaces-made-simple/" target="_blank" rel="noreferrer noopener">namespace </a>(they have no names). The syntax is: <code>lambda &lt;argument name(s)> : &lt;return expression></code>. You’ll see an example next, where each function argument is mapped to its string representation.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(''.join(map(lambda x: str(x), lst)))
# 0124</pre>
<p>This method is a more functional programming style—and some Python coders prefer that. However, Python’s creator <a rel="noreferrer noopener" href="https://blog.finxter.com/about-guidos-fate-of-reduce-in-python-3000/" target="_blank">Guido van Rossum preferred list comprehension over functional programming</a> because of the readability. That’s why Methods 1-3 should be preferred in general. </p>
<p>If you absolutely want to take functional programming, use the next version:</p>
<h2>Method 5: Join + Map + Str</h2>
<p>There’s no need to use the lambda function to transform each list element to a string representation—if there’s a built-in function that’s already doing exactly this: the <code>str(...)</code> function you’ve already seen! </p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(''.join(map(str, lst)))
# 0124</pre>
<p>Because of its <a href="https://blog.finxter.com/10-python-one-liners/" target="_blank" rel="noreferrer noopener">conciseness and elegance</a>, passing the <code>str</code> function name as a function argument into the <code>map</code> function is the most Pythonic <em>functional </em>way of solving this problem.</p>
<h2>Method 6: Simple Loop + Str (Naive)</h2>
<p>Sure, you can also solve the problem in a non-Pythonic way by using a simple <a href="https://blog.finxter.com/python-one-line-for-loop-a-simple-tutorial/" target="_blank" rel="noreferrer noopener">for loop</a> and build up the string:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">s = ''
for x in lst: s += str(x)
print(s)
# 0124</pre>
<p>But that’s not only less <a href="https://pythononeliners.com/" target="_blank" rel="noreferrer noopener">concise</a>, it’s also less efficient. So, a master coder in Python would never use such a method!</p>
<p>If you want to become a Python master coder, check out my <a rel="noreferrer noopener" href="https://blog.finxter.com/subscribe/" target="_blank">free in-depth Python email course</a>. Join tens of thousands of ambitious Python coders and become a Python master the automatic way!</p>
<h2>Where to Go From Here?</h2>
<p>Enough theory, let’s get some practice!</p>
<p>To become successful in coding, you need to get out there and solve real problems for real people. That’s how you can become a six-figure earner easily. And that’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?</p>
<p><strong>Practice projects is how you sharpen your saw in coding!</strong></p>
<p>Do you want to become a code master by focusing on practical code projects that actually earn you money and solve problems for people?</p>
<p>Then become a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.</p>
<p>Join my free webinar <a rel="noreferrer noopener" href="https://blog.finxter.com/webinar-freelancer/" target="_blank">“How to Build Your High-Income Skill Python”</a> and watch how I grew my coding business online and how you can, too—from the comfort of your own home.</p>
<p><a href="https://blog.finxter.com/webinar-freelancer/" target="_blank" rel="noreferrer noopener">Join the free webinar now!</a></p></p>
</div>


https://www.sickgaming.net/blog/2020/06/16/how-to-use-pythons-join-on-a-list-of-objects-not-strings/