你了解女巫们的黑魔法么?-Python 迭代器


迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。

迭代器:每次调用 实现 next 方法,返回一个结果 ,知道结束 返回 ` StopIteration ` 异常

迭代器只能迭代一次

很多时候我们使用的 for 循环 遍历一些 列表集合字符串 等对象,而这些对象通常就被称为可迭代对象 ,迭代器协议 就是 实现 可迭代对象的协议 简单来说: for 循环使用了迭代器来迭代对象

In [14]: a = [ 1, 2, 3, 4 ]

In [15]: max(a)
Out[15]: 4

In [16]: min(a)
Out[16]: 1

In [17]: sum(a)
Out[17]: 10

In [18]: type(a)
Out[18]: list

In [19]: b = iter(a)

In [20]: sum(b)
Out[20]: 10

In [21]: type(b)
Out[21]: listiterator

In [22]: b
Out[22]: <listiterator at 0x4a04278>

函数式的处理

map() , reduce()filter() 函数

map 就是把一些操作分给不同的机器 ,reduce 就是把操作的结果汇总

在Python中 map 就是对列表里面的每一项应用一个操作 reduce 就是把所有的结果给累计起来 filter 过滤的作用,map 没有

a = (1, 2, 3, 4)
map(abs, (-2, 3, -4))
reduce(lambda x, y: x*y, a)
filter(lambda x: x % 2 != 0, a)


In [127]: map(abs, (-2, 3, -4))
Out[127]: [2, 3, 4]

In [130]: a = (1, 2, 3, 4)

In [131]: reduce(lambda x, y: x*y, a)
Out[131]: 24

In [132]: filter(lambda x: x % 2 != 0, a)
Out[132]: (1, 3)


itertools 库

一个实现迭代器的 库

In [133]: import itertools
In [134]: itertools?
Type:        module
String form: <module 'itertools' (built-in)>
Docstring:
Functional tools for creating and using iterators.

Infinite iterators:
count([n]) --> n, n+1, n+2, ...
cycle(p) --> p0, p1, ... plast, p0, p1, ...
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times

Iterators terminating on the shortest input sequence:
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...
compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...
dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails
groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)
ifilter(pred, seq) --> elements of seq where pred(elem) is True
ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False
islice(seq, [start,] stop [, step]) --> elements from
       seq[start:stop:step]
imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n
takewhile(pred, seq) --> seq[0], seq[1], until pred fails
izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...
izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...

Combinatoric generators:
product(p, q, ... [repeat=1]) --> cartesian product
permutations(p[, r])
combinations(p, r)
combinations_with_replacement(p, r)

#方法:

itertools.chain		# 一次迭代多个列表,并且不会生成中间列表
itertools.combinations		# 列表元素的组合
itertools.combinations_with_replacement
itertools.compress
itertools.count		# 创建无限序列
itertools.cycle		# 重复遍历列表中的值
itertools.dropwhile		# 过滤列表中的元素, 返回True或False
itertools.groupby		# 返回一个产生按照key进行分组后的值集合的迭代器
itertools.ifilter		# 类似于列表中的filter(),但是返回的是一个循环器
itertools.ifilterfalse		# 和ifilter 函数相反 , 返回 false 项的迭代器
itertools.imap		# 与map()函数功能相似,只不过返回的不是序列,而是一个循环器
itertools.islice		# 返回输入迭代器根据索引来选取的项
itertools.izip		# 列表连接
itertools.izip_longest		# 按照最长的列表进行连接,没有对应的就返回 None
itertools.permutations		# 所有可能的排列
itertools.product		# 笛卡尔积
itertools.repeat		# 创建返回对象多次的迭代器
itertools.starmap
itertools.takewhile
itertools.tee		# 生成多个迭代器

详细介绍几个常用的方法:

itertools.chain

一次迭代多个列表,把多个列表连接起来, 一个一个的访问, 并且不会生成中间列表

In [8]: itertools.chain?
Docstring:
chain(*iterables) --> chain object

Return a chain object whose .next() method returns elements from the
first iterable until it is exhausted, then elements from the next
iterable, until all of the iterables are exhausted.
Type:      type

例如:

In [9]: import itertools

In [10]: a = (5, 6, 7, 8)

In [11]: a
Out[11]: (5, 6, 7, 8)

In [12]: for b in itertools.chain((1, 2, 3, 4), a):
    ...:     print b
    ...:
1
2
3
4
5
6
7
8

itertools.cycle

重复遍历列表中的值 , 有一个参数就是遍历的列表


In [29]: itertools.cycle?
Docstring:
cycle(iterable) --> cycle object

Return elements from the iterable until it is exhausted.
Then repeat the sequence indefinitely.
Type:      type

例如:

In [30]: for b in itertools.cycle( ("a1", "a2", "a3" ) ):
    ...:     print b
    ...:
a1
a2
a3
a1
a2
a3
a1
.......................................
# Ctrl + c 结束,或者指定结束

In [35]: a = 0

In [36]: for b in itertools.cycle( ("a1", "a2", "a3" ) ):
    ...:     a += 1
    ...:     if a ==10:
    ...:         break
    ...:     print (a ,b)
    ...:
(1, 'a1')
(2, 'a2')
(3, 'a3')
(4, 'a1')
(5, 'a2')
(6, 'a3')
(7, 'a1')
(8, 'a2')
(9, 'a3')

itertools.count

创建 一个无限值的 序列

In [3]: itertools.count?
Docstring:
count(start=0, step=1) --> count object

Return a count object whose .next() method returns consecutive values.
Equivalent to:

    def count(firstval=0, step=1):
        x = firstval
        while 1:
            yield x
            x += step
Type:      type

itertools.count 有两个参数: start 开始 默认为0 ` step` 步长 默认为1

In [24]: a = itertools.count(1,1)

In [24]: a
Out[24]: count(1)

In [25]: for b in a :
    ...:     print b
    ...:
1
2
3
4
5
6
.......................................
# Ctrl + c 结束,或者指定结束

In [26]: a = itertools.count(1,1)

In [27]: a
Out[27]: count(1)

In [28]: for b in a :
    ...:     if b == 5:
    ...:         break
    ...:     print b
    ...:
1
2
3
4



In [1]: import itertools

In [2]: a = ("a1", "a2", "a3", "a4")

In [3]: a
Out[3]: ('a1', 'a2', 'a3', 'a4')

In [4]: zip (itertools.count(1,1), a)
Out[4]: [(1, 'a1'), (2, 'a2'), (3, 'a3'), (4, 'a4')]

# 不生成列表的形式,而是返回一个迭代器对象,当循环调用的时候,循环一次生成一个元素
In [6]: itertools.izip (itertools.count(1,1), a)
Out[6]: <itertools.izip at 0x431b9c8>

In [7]: for b in itertools.izip (itertools.count(1,1), a):
   ...:     print b
   ...:
(1, 'a1')
(2, 'a2')
(3, 'a3')
(4, 'a4')

itertools.dropwhile

当函数执行时返回True的时候 迭代结束,否则继续进行迭代

In [61]: itertools.dropwhile?
Docstring:
dropwhile(predicate, iterable) --> dropwhile object

Drop items from the iterable while predicate(item) is true.
Afterwards, return every element until the iterable is exhausted.
Type:      type

例如:


In [64]: def whether_one(x):
    ...:     print "not is one", x
    ...:     return (x!=1)
    ...:

In [65]: for b in itertools.dropwhile(whether_one, [ 2, 5, -3, 1, 2, -4, 1, 0 ]):
    ...:     print "is one", b
    ...:
not is one 2
not is one 5
not is one -3
not is one 1
is one 1
is one 2
is one -4
is one 1
is one 0

itertools.ifilter

用法类似于列表里面的 ` filter( )` 函数

In [86]: itertools.ifilter?
Docstring:
ifilter(function or None, sequence) --> ifilter object

Return those items of sequence for which function(item) is true.
If function is None, return the items that are true.
Type:      type

例如:

In [83]: def whether_one(x):
    ...:     print "not is one :", x
    ...:     return (x!=1)
    ...:

In [84]: for b in itertools.ifilter(whether_one, [ 2, 5, -3, 1, 2, -4, 1, 0 ]):
    ...:     print "is one :", b
not is one : 2
is one : 2
not is one : 5
is one : 5
not is one : -3
is one : -3
not is one : 1
not is one : 2
is one : 2
not is one : -4
is one : -4
not is one : 1
not is one : 0
is one : 0

itertools.islice

类似于序列切片方式返回迭代器

In [40]: itertools.islice?
Docstring:
islice(iterable, [start,] stop [, step]) --> islice object

Return an iterator whose next() method returns selected values from an
iterable.  If start is specified, will skip all preceding elements;
otherwise, start defaults to zero.  Step defaults to one.  If
specified as another value, step determines how many values are
skipped between successive calls.  Works like a slice() on a list
but returns an iterator.
Type:      type

例如:

for a in itertools.islice(itertools.count(), 5):
    print a


In [43]: for a in itertools.islice(itertools.count(), 5):
    ...:     print a
    ...:
0
1
2
3
4

itertools.tee

由于迭代器只能迭代一次,所以使用itertools.tee可以生成多个迭代器, 默认是两个

In [49]: itertools.tee?
Docstring: tee(iterable, n=2) --> tuple of n independent iterators.
Type:      builtin_function_or_method

例如:

In [46]: a = (1, 2, 3)

In [47]: a
Out[47]: (1, 2, 3)

In [48]: a1, a2, a3 = itertools.tee(a,3)

In [49]: for b in a1:
    ...:     print b
    ...:
1
2
3

In [50]: for b in a1:
    ...:     print b
    ...:

In [51]: for b in a2:
    ...:     print b
    ...:
1
2
3

itertools.izip & itertools.izip_logest

itertools.izip_logest 按照最长的列表进行连接,没有对应的就返回 None

In [54]: for b in itertools.izip( ("a1", "a2", "a3"), (1, 2, 3, 4, 5)):
    ...:     print b
    ...:
('a1', 1)
('a2', 2)
('a3', 3)

In [55]: for b in itertools.izip_longest( ("a1", "a2", "a3"), (1, 2, 3, 4, 5)):
    ...:     print b
    ...:
('a1', 1)
('a2', 2)
('a3', 3)
(None, 4)
(None, 5)

itertools.permutations

列出所有可能的排列

In [68]: itertools.permutations?
Docstring:
permutations(iterable[, r]) --> permutations object

Return successive r-length permutations of elements in the iterable.

permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
Type:      type

例如:

In [66]: a = ("a1", "a2", "a3")

In [67]: for b in itertools.permutations(a):
    ...:     print b
    ...:
('a1', 'a2', 'a3')
('a1', 'a3', 'a2')
('a2', 'a1', 'a3')
('a2', 'a3', 'a1')
('a3', 'a1', 'a2')
('a3', 'a2', 'a1')

itertools.combinations

列出所有的组合,和上面的 itertools.permutations 对比看

In [70]: itertools.combinations?
Docstring:
combinations(iterable, r) --> combinations object

Return successive r-length combinations of elements in the iterable.

combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)
Type:      type

例如:


In [74]: a = ("a1", "a2", "a3")

In [75]: for b in itertools.combinations(a, 2):
    ...:     print b
    ...:
('a1', 'a2')
('a1', 'a3')
('a2', 'a3')

In [76]: for b in itertools.combinations(a, 3):
    ...:     print b
    ...:
('a1', 'a2', 'a3')

itertools.product

笛卡尔积

第一个列表的某一项和第二个列表的某一项

In [79]: itertools.product?
Docstring:
product(*iterables) --> product object

Cartesian product of input iterables.  Equivalent to nested for-loops.

For example, product(A, B) returns the same as:  ((x,y) for x in A for y in B).
The leftmost iterators are in the outermost for-loop, so the output tuples
cycle in a manner similar to an odometer (with the rightmost element changing
on every iteration).

To compute the product of an iterable with itself, specify the number
of repetitions with the optional repeat keyword argument. For example,
product(A, repeat=4) means the same as product(A, A, A, A).

product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)
product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...
Type:      type

例如:

In [81]: itertools.product('ab', range(3))
Out[81]: <itertools.product at 0x44b4090>

In [82]: for b in itertools.product('ab', range(3)):
    ...:     print b
    ...:
('a', 0)
('a', 1)
('a', 2)
('b', 0)
('b', 1)
('b', 2)

itertools.repeat

创建返回对象多次的迭代器


In [60]: itertools.repeat?
Docstring:
repeat(object [,times]) -> create an iterator which returns the object
for the specified number of times.  If not specified, returns the object
endlessly.
Type:      type

例如:

In [59]: list(itertools.repeat("hello", 4))
Out[59]: ['hello', 'hello', 'hello', 'hello']


Python 简单数据 & 语法


is 和 ==

== 两个被引用的对象是否具有相同的值,也就是两个对象的值相等

is 两个被引用的对象是否是同一个对象 id( a ) == id( b )

In [13]: a=(1,2)

In [14]: b = (1,2)

In [15]: a is b
Out[15]: False

In [16]: a == b
Out[16]: True

In [17]: id (a)
Out[17]: 63264456L

In [19]: id (b)
Out[19]: 63286856L

In [20]: a=(1,2)

In [21]: b=a

In [22]: a==b
Out[22]: True

In [23]: a is b
Out[23]: True

In [24]:

函数参数

对于Python中 函数的参数 既不是传值也不是传引用,传递的是 对象的引用,函数在参数传递的过程中,把整个对象传进去,对不可变的对象(比如说 字符串) 由于不能修改 所以 如果修改的话是通过生成一个新的对象 来实现,对于可以改变的对象来说 (比如说列表 ) 修改的话对不论是对外部还是内部都都可变

例如:

字符串


In [38]: def a(string):
    ...:     string = "li"
    ...:

In [39]: name = "zhang"

In [40]: print name
zhang

In [41]: a(name)

In [42]: print name
zhang

列表

In [1]: def a(list_1):
   ...:     list_1[0]=0
   ...:

In [2]: list_2=[5,10]

In [3]: a(list_2)

In [4]: print list_2
[0, 10]

字符串是不可变的,如果要修改字符串的话可以通过切割 连接 比如 ` + 或者 join 另外还有 % format `

但是通常情况下 推荐使用 join 因为 + 会生成很多中间结果 比如说有a1 a2 a3 a4 a5 a6 ...... an个字符串需要连接 如果用 + 的话会生成很多中间结果 ,占用很多内存 a1a2 a1a2a3 a1a2a3a4 a1a2a3a4a5 a1a2a3a4a5a6 ....... a1a2a3a4a5a6...an

但是 join 会一次性连接生成字符串

列表 与 列表解析

列表支持计算操作

[ 1 ] * 10

In [16]: [ 1 ] * 10
Out[16]: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

列表的修改

In [17]: a = [1,2,3,4,5]

In [18]: a = a[1:] + [6]

In [19]: a
Out[19]: [2, 3, 4, 5, 6]

列表解析

[ i*i for i in range(10) ]

In [8]: [ i*i for i in range(10) ]
Out[8]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

[ i*i for i in range(10) if i % 2 == 0 ]

In [9]:  [ i*i for i in range(10) if i % 2 == 0 ]
Out[9]: [0, 4, 16, 36, 64]

列出某个目录下面所有的目录的列表

[ items for items in os.listdir('/usr/local')]

In [14]: import os

In [15]: [ items for items in os.listdir('/usr/local')]
Out[15]: 
['bin',
 '.git',
 'aegis',
 'games',
 'yagmail-0.5.148',
 'include',
.......................

列表输出以 /usr/local 下 .py 结尾的所有文件

In [28]: import glob

In [29]: [os.path.realpath(items) for items in glob.glob("/usr/local/*.py")]
Out[29]: 
['/usr/local/login_auth.py',
 '/usr/local/yagmail.py',
 '/usr/local/mysql_backup.py']

字典

初始化有三种方式:

字典也有字典推导 和列表解析相似

{ i : i * i for i in range(5, 10) if i % 2 != 0}

In [23]: { i : i * i for i in range(5, 10) if i % 2 != 0}
Out[23]: {5: 25, 7: 49, 9: 81}

介绍一个 collection 标准库里面的 defaultdict 方法


In [27]: bb = '1111222233334444'

In [28]: dict_1 ={}

In [29]: for b in bb:
    ...:     dict_1[b] += 1
    ...: print dict_1
    ...:
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-29-5f5c9103785d> in <module>()
      1 for b in bb:
----> 2     dict_1[b] += 1
      3 print dict_1

KeyError: '1'

因为:当请求字典对象里面没有的key时,python会抛出异常KeyError

所以此时可以用到 defaultdict 方法 给字典value元素添加默认类型


In [30]: import collections

In [31]: bb = '1111222233334444'

In [32]: dict_2 = collections.defaultdict(int)

In [33]: for b in bb:
    ...:     dict_2[b] += 1
    ...: print dict_2
    ...:
defaultdict(<type 'int'>, {'1': 4, '3': 4, '2': 4, '4': 4})

if

if elif else

a = int(raw_input("Please input a = "))
b = int(raw_input("Please input b = "))
if a > b:
    print "The b is bigger"
elif a < b :
    print "The a is bigger"
else :
    print "a = b !"

else并不是和最近的if是一对,因为Python通过代码缩进 实现代码块 比如说

if x:
	fi y:
		a1
else
	a2	

while

while 1 :
	print "假"
else 		# 可选
	print "真"

for

序列迭代器 , 一般迭代对象集合列表 字典 等等

In [60]: for i in range(10):
   ...:     if i % 2 == 0:
   ...:         print i*i
   ...:     if i % 2 != 0:
   ...:         print 0
   ...: else:
   ...:     print "finish"
   ...:
0
0
4
0
16
0
36
0
64
0
finish

In [5]: a = dict( a1 = 1, a2 = 2, a3 = 3 )

In [6]: a
Out[6]: {'a1': 1, 'a2': 2, 'a3': 3}

In [7]: for key,value in a :
   ...:     print key,value
   ...:
a 1
a 3
a 2

zip

查看一下帮助文档

In [8]: zip?
Docstring:
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

Return a list of tuples, where each tuple contains the i-th element
from each of the argument sequences.  The returned list is truncated
in length to the length of the shortest argument sequence.
Type:      builtin_function_or_method

经常被用于字典初始化

In [10]: aa = ("a", "b", "c")

In [11]: bb = (1, 2, 3)

In [12]: dict_1 = dict(zip(aa, bb))

In [13]: dict_1
Out[13]: {'a': 1, 'b': 2, 'c': 3}

升级MySQL 5.7

好久没登阿里云了,今天上去了,发现我的 MySQL 版本有点低,算了 先升级一下吧,上图


解压

Alt text

移动

Alt text

把当前的 mysql 实例关闭:

Alt text

以前是指向5.6 的现在指向5.7

Alt text

Alt text

重新启动报错

Alt text

解决

Alt text

Alt text

Alt text

Alt text

Alt text

重启: Alt text


Git操作pull & fetch

pull 和 fetch 区别


pull 作用相当于说从远程拉取某一个分支并且合并当前分支到该 分支:相当于做了两个动作:一个是拉取 一个是合并( merge ),产生的结果是,本地分支会有远程库所拉取分支的内容,但是并不会默认产生与远程名相同的分支

同样 fetch 会拉取远程分支到本地库,但是不会在本地创建与之名字相同的分支,如果想用远程的分支 可以 checkout 远程分支的名字就能切换到远程分支名字相同的分支 (创建了与远程库相同名字的分支并且切换到对应名字分支上去)

pull = fetch + merge

在分支操作中 pull 操作基本禁用,因为 不能随意合并分支。

所以操作远程库分支的标准操作是:

git fetch origin 远程分支名字:远程分支名字 既会拉取远程库分支到本地分支,并且在本地创建与之对应的分支

这个就是远程分支与本地分支的对应 push 一定是分支对分支

git push -u origin 分支名字:分支名字

这回长记性了 ,差点坏了大事


私について


私は Li と申します、ま、ソフトウェアを学びながら、日本語を学び、まだ大学はまだ卒業がありません。実は、本当の話を言って、私はとても日本語を学びが好きでないで、しかし専門の原因のために、どうしても日本語を引き続き学ばなければなりません

私はも趣味は 何もないようです、もしもどうしてもある話を言わなければならなくて、たぶん歌を聞くで、すこしたたくコードがあるいは一回コードをたたいて一回が漫才を聞きます 。もしもぼんやりして興味だと言えて、それでは私もよく一人でぼんやりすることが好きです。それぞれ大きいウェブサイトをぶらぶらすることが好きで、 Wiki とか GitHub とか、 みんなの書いた良い文章を見てみて、ニュースを見てみます、Google が好きです。時間がある時はまた よく自分の Bloggerのサイトを 直して、少し美化して、あるいは以前出すことがある文章を見てみます

以前とても ドラマ を見たことが好きで、多くの脳の不完全なドラマをも見たことがあって、まだ 多くの 脳の不完全な 小説を読んだことがあります、今 本当に非常が バカ なことを思い出します。当時から嫌いな いくつかの国産の劇と韓の劇、今もゆっくりするに自分の好きな作品、特にたくさんですばらしい映画あるいはドラマを探します。同時に私も特に崇拝するスターは何もなくて、もしもどうしてもあると言わなければならなくて、“哥哥” 张国荣 はひとつの計算しましょう

私が1つのとても大きい欠点がまだあるのは、変化しやすくて、私の同じく努力していたのはこの欠点をすっかり直しに行きます。

私はも接触したプログラミング言語が多くなくて、Python は計算することができるのが上最も好きな言語でしたと言える、その次にShellです(もちろんで、多くの人もあってShellを感じるのは ひとつの言語だと言えません)

美しい物事,それとも美しい人が全く抵抗力がないのだであろうと、だから私はとても Python が好きです

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

ソフトウェアの方面もいくつかデータベースの方面の知識に接触したことがあります。MySQL とか MongoDB とか 、今 MySQL の InnoDB に対してとても興味を持ちます。

今まで、たいへん Windows システムが嫌いで、とても Mac システムのが好きで、しかしまだ学生で、ずっと平気で家とあまりお金を要して Mac をかえありません だからしばらく 同じく とても好きな Linux の Ubuntu を設置しました 。

短い時間の内の理想は 杭州の仕事に卒業していくので、しかし 変わりがありを計画して、誰もは っきり分からない 、だから 私が 努力して行って自分を更に充実していさせます


Pagination