<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Data-Structures on AW — notes &amp; thoughts</title><link>https://coffepowered.github.io/tags/data-structures/</link><description>Recent content in Data-Structures on AW — notes &amp; thoughts</description><generator>Hugo -- gohugo.io</generator><language>it-IT</language><managingEditor>Andrea Ruggerini</managingEditor><webMaster>Andrea Ruggerini</webMaster><lastBuildDate>Mon, 11 Jan 2021 21:28:43 -0500</lastBuildDate><atom:link href="https://coffepowered.github.io/tags/data-structures/index.xml" rel="self" type="application/rss+xml"/><item><title>Short notes on namedtuples, NamedTuples and Data classes</title><link>https://coffepowered.github.io/blogs/python-data-typer-for-data/</link><pubDate>Mon, 11 Jan 2021 21:28:43 -0500</pubDate><guid>https://coffepowered.github.io/blogs/python-data-typer-for-data/</guid><description>&lt;p&gt;Both dataclasses and tuples are based on the &lt;a href="https://www.attrs.org/en/stable/"&gt;attrs&lt;/a&gt; project, the one Python Library &lt;a href="https://glyph.twistedmatrix.com/2016/08/attrs.html"&gt;everybody needs&lt;/a&gt; and are fast object types (&lt;a href="https://refactoring.guru/design-patterns/factory-method"&gt;factory methods&lt;/a&gt;) designed to simplify and reduce code.&lt;/p&gt;
&lt;h2 id="namedtuple-and-namedtuple"&gt;namedtuple and NamedTuple&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Both &lt;code&gt;immutable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Tuple-based (hence fast) but far &lt;a href="https://www.attrs.org/en/stable/why.html"&gt;better&lt;/a&gt; than tuples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NamedTuple&lt;/strong&gt; is the typed version of &lt;strong&gt;namedtuple&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;immutable, iterable, hashable, unpackable&lt;/li&gt;
&lt;li&gt;backward-compatible with &lt;strong&gt;tuple&lt;/strong&gt; (e.g you can access a namedtuple by index)&lt;/li&gt;
&lt;li&gt;default arguments supported from Python 3.7+&lt;/li&gt;
&lt;li&gt;fast! C-based&lt;/li&gt;
&lt;li&gt;example &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Point &lt;span style="color:#f92672"&gt;=&lt;/span&gt; namedtuple(&lt;span style="color:#e6db74"&gt;&amp;#39;Point&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;x y&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pt1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Point(&lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5.0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pt2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Point(&lt;span style="color:#ae81ff"&gt;2.5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1.5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; math &lt;span style="color:#f92672"&gt;import&lt;/span&gt; sqrt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# use index referencing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;line_length &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sqrt((pt1[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]&lt;span style="color:#f92672"&gt;-&lt;/span&gt;pt2[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;])&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; (pt1[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]&lt;span style="color:#f92672"&gt;-&lt;/span&gt;pt2[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;])&lt;span style="color:#f92672"&gt;**&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# use tuple unpacking&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;x1, y1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pt1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="dataclasses"&gt;Dataclasses&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Are &lt;code&gt;mutable&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/dataclasses.html"&gt;post-init processing&lt;/a&gt; can be used to create fields depending on other fields or even to perform input validation&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;all implementation is written in Python, so &lt;a href="https://stackoverflow.com/questions/51671699/data-classes-vs-typing-namedtuple-primary-use-cases"&gt;slower&lt;/a&gt; wrt tuple-based data types&lt;/li&gt;
&lt;li&gt;Validation of types at runtime not supported natively (or &lt;a href="https://stackoverflow.com/questions/50563546/validating-detailed-types-in-python-dataclasses"&gt;cumbersome&lt;/a&gt;) but easy with decorator &lt;a href="https://pypi.org/project/enforce-typing/"&gt;@enforce_typing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;from Python 3.7&lt;/li&gt;
&lt;li&gt;are just regular Classes (e.g. inheritance) withot writing boilerplate code&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.python.org/dev/peps/pep-0557/#why-not-just-use-namedtuple"&gt;inappropriate&lt;/a&gt; when API compatibility with tuples or dicts is requested&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=T-TwcmT6Rcw&amp;amp;t=1390"&gt;bonus&lt;/a&gt; PyCon talk, if you have time&lt;/li&gt;
&lt;li&gt;example&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; dataclasses &lt;span style="color:#f92672"&gt;import&lt;/span&gt; dataclass
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@dataclass&lt;/span&gt;(unsafe_hash&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;InventoryItem&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&amp;#39;Class for keeping track of an item in inventory.&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: str
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; unit_price: float
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; quantity_on_hand: int &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;total_cost&lt;/span&gt;(self) &lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt; float:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;unit_price &lt;span style="color:#f92672"&gt;*&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;quantity_on_hand
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="other-fancy-data-types-not-from-the-stdlib"&gt;Other fancy data types (not from the stdlib)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pydantic-docs.helpmanual.io/"&gt;pydantic&lt;/a&gt;: enforces type hints at runtime providing user-readable errors when data is invalid. Seems relatively popular.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sample input val via Regexp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; dataclasses &lt;span style="color:#f92672"&gt;import&lt;/span&gt; dataclass
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; re
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;@dataclass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Widget&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id: int
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__post_init__&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id_condition &lt;span style="color:#f92672"&gt;=&lt;/span&gt; re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;match&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;r&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;[0-9]&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{4}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, str(self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;id))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; id_condition:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;id&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; doesn&amp;#39;t follow pattern [0-9]&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;&amp;#123;&amp;#123;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;4&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;&amp;#125;&amp;#125;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;raise&lt;/span&gt; CustomException
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python"&gt;brief&lt;/a&gt; explanation on stackoverlow&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>