【3】数据分析-3-1-python迭代工具--itertools

读取指定行数的数据的时候,接触到了itertools,既然接触了,那就好好了解一下。

使用Python提供的itertools工具,我们可以避免此类问题。itertools的目的就是为了提搞looping的效率。itertools模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是迭代对象,只有用for循环迭代的时候才真正计算

一、 无限迭代器

1.count()

count(start[, step])

>>> import itertools
>>> seq=itertools.count(4)
>>> for i in seq:
 print i

4
5
6
7
8
9
10
…

因为count()会创建一个无限的迭代器,所以上述代码会打印出自然数序列,根本停不下来,只能按 Ctrl+C 退出。

2.cycle()

>>> cs=itertools.cycle("abcd")
>>> for c in cs:
 print c

a
b
c
d
a
b
c
d
…

3. repeat()

负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数:

>>> ns = itertools.repeat('A', 10)
>>> for n in ns:
... print n
...
打印10次'A'

4. takewhile()

无限序列虽然可以无限迭代下去,但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列:

>>> natuals = itertools.count(1)
>>> ns = itertools.takewhile(lambda x: x <= 10, natuals)
>>> for n in ns:
... print n
...
打印出1到10

二.其他的几个迭代函数

5. chain()

>>> for c in itertools.chain("abc","123"):
print c


a
b
c
1
2
3

6. groupby()

groupby()把迭代器中相邻的重复元素挑出来放在一起:

groupby(iterable[, keyfunc])

>>> for key, group in itertools.groupby('AAABBBCCAAA'):
	print key, list(group) 
	
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']

实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。如果我们要忽略大小写分组,就可以让元素’A’和’a’都返回相同的key:

>>> for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
	print key, list(group)

输出:

A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']

示例:

from itertools import *
a = ['aa', 'ab', 'abc', 'bcd', 'abcde']
for i, k in groupby(a, len):#按照字符串的长度对a的每个元素进行分组
	for m in k:
	print m, 
	print i

输出:

aa ab 2
abc bcd 3
abcde 5

7.imap()

imap()和map()的区别在于,imap()

可以作用于无穷序列,并且,如果两个序列的长度不一致,以短的那个为准。

>>> for x in itertools.imap(lambda x, y: x * y, [10, 20, 30], itertools.count(1)):
... print x
...
10
40
90

注意imap()返回一个迭代对象,而map()返回list。当你调用map()时,已经计算完毕:

>>> r = map(lambda x: x*x, [1, 2, 3])
>>> r # r已经计算出来了
[1, 4, 9]
当你调用imap()时,并没有进行任何计算:

>>> r = itertools.imap(lambda x: x*x, [1, 2, 3])
>>> r
<itertools.imap object at 0x103d3ff90>
# r只是一个迭代对象
必须用for循环对r进行迭代,才会在每次循环过程中计算出下一个元素:

>>> for x in r:
... print x
...
1 
4
9

8. ifilter()

不用多说了,ifilter()就是filter()的惰性实现。

9.islice

islice(seq[, start], stop[, step])

Python读取指定行数

例一:不读取第一行

from itertools import islice

input_file = open("C:\\Python34\\test.csv") 
for line in islice(input_file, 1, None): 
do_readline()

例二:读取前两行

for each_line in islice(data, 0, 2):
 print each_line

10.izip

izip(*iterator)
import itertools 
listone = ['a','b','c'] 
listtwo = ['11','22','abc'] 
listthree = listone + listtwo 
for item in itertools.izip(listone,listtwo): 
	print item

结果:

('a', '11') ('b', '22') ('c', 'abc')

功能:返回迭代器,项目是元组,元组来自*iterator的组合

11 product 每个list中选择一个

list(itertools.product([1, 5, 8], [0.5, 4]))

[(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]

例如:

aa =[[1, 5, 8], [0.5, 4],['a','m']]
list(itertools.product(*aa))

[(1, 0.5, 'a'),
 (1, 0.5, 'm'),
 (1, 4, 'a'),
 (1, 4, 'm'),
 (5, 0.5, 'a'),
 (5, 0.5, 'm'),
 (5, 4, 'a'),
 (5, 4, 'm'),
 (8, 0.5, 'a'),
 (8, 0.5, 'm'),
 (8, 4, 'a'),
 (8, 4, 'm')]
  • 这个星号是亮点呀!
  • 另存为list后,有可能占用很大的内存,可以直接 for one_list in itertools.product(*aa) 来遍历,减少内存消耗

PS

更多功能的解读与应用等用到的时候再回来研究:

product('ABCD', repeat=2)	 	AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)	 	AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)	 	AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2)	 	AA AB AC AD BB BC BD CC CD DD

参考资料

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn