<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Elasticsearch on 庞玉栋个人博客</title><link>https://pangyd.com/tags/elasticsearch/</link><description>Recent content in Elasticsearch on 庞玉栋个人博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 05 Mar 2020 22:43:00 +0800</lastBuildDate><atom:link href="https://pangyd.com/tags/elasticsearch/index.xml" rel="self" type="application/rss+xml"/><item><title>Collections 内建集合模块</title><link>https://pangyd.com/post/231-collections/</link><pubDate>Fri, 28 Feb 2020 17:01:13 +0800</pubDate><guid>https://pangyd.com/post/231-collections/</guid><description>&lt;p>&lt;/p>&lt;p>&lt;span lang="EN-US">Collections&amp;nbsp;&lt;/span>集合类&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;h3>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/h3>&lt;p>我们知道&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>可以表示不变集合，例如，一个点的二维坐标就可以表示成：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p = (&lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">)&lt;/span>&lt;/code>&lt;/pre>&lt;p>但是，看到&lt;code>&lt;span lang="EN-US">(1, 2)&lt;/span>&lt;/code>，很难看出这个&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>是用来表示一个坐标的。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>定义一个&lt;span lang="EN-US">class&lt;/span>又小题大做了，这时，&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>就派上了用场：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;span class="keyword">&lt;span lang="EN-US">from&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> collections &lt;/span>&lt;/code>&lt;span class="keyword">&lt;span lang="EN-US">import&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> namedtuple&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">Point = namedtuple(&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'Point'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, [&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'x'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'y'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">])&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p = Point(&lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p.x&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="number">&lt;span lang="EN-US">1&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">p.y&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="number">&lt;span lang="EN-US">2&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;p>&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>是一个函数，它用来创建一个自定义的&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>对象，并且规定了&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>元素的个数，并可以用属性而不是索引来引用&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>的某个元素。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>这样一来，我们用&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>可以很方便地定义一种数据类型，它具备&lt;span lang="EN-US">tuple&lt;/span>的不变性，又可以根据属性来引用，使用十分方便。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>可以验证创建的&lt;code>&lt;span lang="EN-US">Point&lt;/span>&lt;/code>对象是&lt;code>&lt;span lang="EN-US">tuple&lt;/span>&lt;/code>的一种子类：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">isinstance(p, Point)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="builtin">&lt;span lang="EN-US">True&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="prompt">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; &lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">isinstance(p, tuple)&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="builtin">&lt;span lang="EN-US">True&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;p>类似的，如果要用坐标和半径表示一个圆，也可以用&lt;code>&lt;span lang="EN-US">namedtuple&lt;/span>&lt;/code>定义：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;pre>&lt;span class="comment">&lt;span lang="EN-US"># namedtuple('&lt;/span>名称&lt;span lang="EN-US">', [&lt;/span>属性&lt;span lang="EN-US">list]):&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">&lt;/span>&lt;/code>&lt;/pre>&lt;pre>&lt;span class="constant">&lt;span lang="EN-US">Circle&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US"> = namedtuple(&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'Circle'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, [&lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'x'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'y'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">, &lt;/span>&lt;/code>&lt;span class="string">&lt;span lang="EN-US">'r'&lt;/span>&lt;/span>&lt;code>&lt;span lang="EN-US">])&lt;/span>&lt;/code>&lt;/pre>&lt;p>&lt;span lang="EN-US">&amp;nbsp;&lt;/span>&lt;/p>&lt;p>&lt;b>&lt;span lang="EN-US">Deque&lt;/span>&lt;/b>&lt;span lang="EN-US">&amp;nbsp;&amp;nbsp;&lt;/span>双向队列&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>使用&lt;code>&lt;span lang="EN-US">list&lt;/span>&lt;/code>存储数据时，按索引访问元素很快，但是插入和删除元素就很慢了，因为&lt;code>&lt;span lang="EN-US">list&lt;/span>&lt;/code>是线性存储，数据量大的时候，插入和删除效率很低。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>&lt;span lang="EN-US">deque&lt;/span>是为了高效实现插入和删除操作的双向列表，适合用于队列和栈：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>&lt;span lang="EN-US">list&lt;/span>是线性存储，数据量大的时候，效率慢&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p>&lt;code>&lt;span lang="EN-US">deque&lt;/span>&lt;/code>除了实现&lt;span lang="EN-US">list&lt;/span>的&lt;code>&lt;span lang="EN-US">append()&lt;/span>&lt;/code>和&lt;code>&lt;span lang="EN-US">pop()&lt;/span>&lt;/code>外，还支持&lt;code>&lt;span lang="EN-US">appendleft()&lt;/span>&lt;/code>和&lt;code>&lt;span lang="EN-US">popleft()&lt;/span>&lt;/code>，这样就可以非常高效地往头部添加或删除元素。&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p align="left">&lt;b>&lt;span lang="EN-US">defaultdict&lt;/span>&lt;/b>&lt;/p>&lt;p align="left">使用&lt;span lang="EN-US">dict&lt;/span>时，如果引用的&lt;span lang="EN-US">Key&lt;/span>不存在，就会抛出&lt;span lang="EN-US">KeyError&lt;/span>。如果希望&lt;span lang="EN-US">key&lt;/span>不存在时，返回一个默认值，就可以用&lt;span lang="EN-US">defaultdict&lt;/span>：&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; from collections import defaultdict&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd = defaultdict(lambda: 'N/A')&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key1'] = 'abc'&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key1'] # key1&lt;/span>存在&lt;span lang="EN-US">&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">'abc'&lt;/span>&lt;/p>&lt;p align="left">&lt;span lang="EN-US">&amp;gt;&amp;gt;&amp;gt; dd['key2'] # key2&lt;/span>不存在，返回默认值&lt;span lang="EN-US">&lt;/span>&lt;/p></description></item></channel></rss>