迭代对象的切片 itertools.islice() 和排列组合permutations(), combinations() 等.
项目快延期了, 一个人干一个项目, 真的是有点难受, 好在大头的数据处理宽表已经 用 sql 拼接出来了, 写了5个大视图拼接了一张物理宽表...也是第一次写过那么长的 sql 了, 心得就是硬怼出来的, 现都还谈不上优化, 能基本怼出来就已经很不错了, 对于目前的我而已. 其实更多的是已经有了的编程思维和sql 思维, 这两个完全不太一样的东西的碰撞吧, 多花点时间, 掌握窍门就会快很多.
现在用的是 mysql 和 IQ, 主要是 IQ, 我写的逻辑其实还是 mysql 风格的, 就很多嵌套, 和子查询, 表关联. 这些步骤都是必须要的, 其实更多是像在硬怼, 但最终还是能够整出来的. 跟面向过程编程的感觉是一样的, 我是觉得特别锻炼逻辑能力的.
然后也逐渐发现呢, 其实 sql 顺序, 会让你感到, 并不是严格按照 from , on, join, where, group by, having, select , distinct, group by, order by limit .. 这样的, 数据库引擎会自动做优化. 当然不同的商业公司的产品可能会不一样的.
简单来个小栗子, 还是以学生表为例.
- 在 mysql 中, 这样写是不可以的, 因为 '姓名' 在 student 表中没有定义的
- 在 IQ 中, 是可以的, 它在执行前, 会把 where 的 '姓名' 类似用以 s_name 替换, 说明引擎是有优化的
但是在 IQ 中, 如果 select 里面有 计算字段, 函数参与的字段, 就会找不到, 就让我很奇怪, 到底是优化还是没有
你会发现, 会给你一种感觉, 执行了 select 的部分, 再执行 group by 的. 也会有一种, 动态编程语言的感觉, 比如 Python 或者 JavaScript, 就执行的时候, 会自己去按一定顺序进行搜索. 具体是怎么实现的, sql 这块我目前也不清楚, 唯一能做的就是去写, 去尝试,如果不行就再再外面, 嵌套一层, 哈哈哈 .
扯远了, 本来是要在看一波迭代器的.
迭代器切片
需求
不通过把迭代器对象全部 list 等方式 "放出来" , 太消耗内存, 只想切片来取一部分.
方案
通过 itertools.islice () 来实现对迭代对象的切片. 不能用 [ ] 这种方式哦
生成器 generator 是不能直接来切片的, 用 itertools.islice( )
其实很好理解, 生成器对象是不能用咱的标准切片的, 因为它的长度, 事先我们并不知道, 而且也没有实现索引.
函数 itertools.islice( ) 会返回一个可以生成指定元素的迭代器, 通过 遍历并丢弃 直到切片开始索引位置的所有元素, 然后才一个个地返回元素, 直到结束嘛.
需要注意的是, islice() 函数会消耗掉传入迭代器中的数据. 必须考虑到, 迭代器是一个不可逆的事实, 就像时间, 流逝了就永远不会再回来.
排列组合的迭代
需求
迭代遍历一个集合中, 元素的所有可能性 (排列或者组合)
方案
通过 itertools 内置模块的 permutations( ), combinations( ), combinations_with_replacement() 这三个已经造好的轮子来计算集合元素的排列组合.
我之前有自己实现过排列组合, 有点忘了是咋搞了, 当时也是参考网上的大佬, 就写起来蛮复杂其实, 留个小 todo, 我先学搬砖, 后面再看看怎么自己来实现一遍吧.
首先是 permutations () 排列嘛, 跟咱数学的东西是一样的. 它接收一个集合对象, 并产生一个元组序列, 是无序的.
从n个元素中取m个元素, 排列数有 : \(A_n^m = n(n-1)(n-2)...(n-m+1) = \frac {n!} {(n-m)!}\)
还可以指定长度的所有排列, 可以传参, 这就很厉害了. 反正暂时我是不会写, 搬砖我是专业的.
同样的, 组合 combinations() 也是类似的用法, 它返回一个集合元素中的所有组合.
从 n 个 中 取 m 个元素, 组合数有: \(C_n^m = \frac {n!}{m!(n-m)!}\)
最后这个 combinations_with_replacement( ) 就咱说的,可放回抽样.
对于 combinations 来说, 元素的顺序其实无所谓的, 都只是一个. 因此在计算组合的时候, 一旦元素被选取, 就会从候选中给剔除掉. 而如果是要实现可放回抽样, 就要这样玩:
小结
- 迭代器对象的切片用 itertools.islice () 方法来实现, 偶尔是会用的
- 排列组合的迭代对象 也用 itertools 里面的 permutations( ), combinations( ), combinations_with_replacement()
- itertools 这个内置模块很香, 值得搬砖, 同时也抽空自己来写一遍排列组合原理, 和数学推导
耐心和恒心, 总会获得回报的.