Jadual Kandungan
前言
PEP8 编码规范
给自己的代码打分
Python奇技淫巧
使用 Counter 进行计数统计
enumerate获取键值对
os.path的使用
善用列表推导式
sort 与 sorted
善用traceback 追踪深层错误
切片操作[]
json.dump()/loads() 存储字典结构
pprint打印结构
zip打包元组
*args和**kw
内建函数 itertools优雅的迭代器
使用with open() as f 来读取文件
使用yield节省内存开销
Rumah pembangunan bahagian belakang Tutorial Python Python 常用的PEP8规范及Python小把戏

Python 常用的PEP8规范及Python小把戏

May 05, 2018 pm 02:50 PM
python spesifikasi

本篇文章的内容是Python 常用PEP8规范及Python小把戏 ,现在分享给大家,有需要的朋友可以看一下这篇文章的内容


前言

从很多地方搬运+总结,以后根据这个标准再将python的一些奇技淫巧结合起来,写出更pythonic的代码~

PEP8 编码规范

英文原版请点击这里

以下是@bobo的整理,原文请见PEP8 Python 编码规范整理代码编排

  1. 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。

  2. 每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。

  3. 类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。

文档编排

  1. 模块内容的顺序:模块说明和docstring—import—globals&constants—其他定义。其中import部分,又按标准、三方和自己编写顺序依次排放,之间空一行

  2. 不要在一句import中多个库,比如import os, sys不推荐

  3. 如果采用from XX import XX引用库,可以省略‘module.’,都是可能出现命名冲突,这时就要采用import XX

空格的使用

  1. 各种右括号前不要加空格。

  2. 逗号、冒号、分号前不要加空格。

  3. 函数的左括号前不要加空格。如Func(1)

  4. 序列的左括号前不要加空格。如list[2]

  5. 操作符左右各加一个空格,不要为了对齐增加空格

  6. 函数默认参数使用的赋值符左右省略空格

  7. 不要将多句语句写在同一行,尽管使用‘;’允许

  8. if/for/while语句中,即使执行语句只有一句,也必须另起一行

注释

总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释!注释必须使用英文,最好是完整的句子,首字母大写,句后要有结束符,结束符后跟两个空格,开始下一句。如果是短语,可以省略结束符。

  1. 块注释,在一段代码前增加的注释。在‘#’后加一空格。段落之间以只有‘#’的行间隔。比如:

# Description : Module config.# # Input : None## Output : None
Salin selepas log masuk
  1. 行注释,在一句代码后加注释。比如:x = x + 1 # Increment x但是这种方式尽量少使用。

  2. 避免无谓的注释。

文档描述

  1. 为所有的共有模块、函数、类、方法写docstrings;非共有的没有必要,但是可以写注释(在def的下一行)。

  2. 单行注释请参考如下方式

def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root    if _kos_root: return _kos_root
    ...
Salin selepas log masuk

命名规则

* 总体原则,新编代码必须按下面命名风格进行,现有库的编码尽量保持风格。绝不要单独使用例如大写的’i’和大写的’o’*

  1. 模块命名尽量短小,使用全部小写的方式,可以使用下划线。

  2. 包命名尽量短小,使用全部小写的方式,不可以使用下划线。

  3. 类的命名使用CapWords的方式,模块内部使用的类采用_CapWords的方式。

  4. 异常命名使用CapWords+Error后缀的方式。

  5. 全局变量尽量只在模块内有效,类似C语言中的static。实现方法有两种,一是all机制;二是前缀一个下划线。

  6. 函数命名使用全部小写的方式,可以使用下划线。

  7. 常量命名使用全部大写的方式,可以使用下划线。

  8. 类的属性(方法和变量)命名使用全部小写的方式,可以使用下划线。

  9. 类的属性有3种作用域public、non-public和subclass API,可以理解成C++中的public、private、protected,non-public属性前,前缀一条下划线。

  10. 类的属性若与关键字名字冲突,后缀一下划线,尽量不要使用缩略等其他方式。

  11. 为避免与子类属性命名冲突,在类的一些属性前,前缀两条下划线。比如:类Foo中声明__a,访问时,只能通过Foo._Foo__a,避免歧义。如果子类也叫Foo,那就无能为力了。

  12. 类的方法第一个参数必须是self,而静态方法第一个参数必须是cls。

编程建议

  1. 编码中考虑到其他python实现的效率等问题,比如运算符‘+’在CPython(Python)中效率很高,都是Jython中却非常低,所以应该采用.join()的方式。

  2. 尽可能使用‘is’‘is not’取代‘==’,比如if x is not None 要优于if x

  3. 使用基于类的异常,每个模块或包都有自己的异常类,此异常类继承自Exception。

  4. 常中不要使用裸露的except,except后跟具体的exceptions。例如

try:
    ...except Exception as ex:    print ex
Salin selepas log masuk
  1. 异常中try的代码尽可能少。

  2. 使用startswith() and endswith()代替切片进行序列前缀或后缀的检查。

foo = 'abc000xyz'if foo.startswith('abc') and foo.endswith('xyz'):    
print 'yes'else:    print 'no'#yes#而如下的方式不提倡if foo[:3]=='abc' and foo[-3:]=='xyz':    
print 'yes'else:    print 'no'
Salin selepas log masuk
  1. 使用isinstance()比较对象的类型。比如:

foo = 'abc000xyz'# 提倡print isinstance(foo,int) # false# 不提倡print type(foo) == type('1') #true
Salin selepas log masuk
  1. 判断序列空或不空,有如下规则:

foo = 'abc000xyz'if foo:    
print "not empty"else:    
print "empty"#不提倡使用如下if len(foo):    
print "not empty"else:    print "empty"
Salin selepas log masuk
  1. 二进制数据判断使用 if boolvalue的方式。

给自己的代码打分

使用pylint进行代码检查,@permilk–Python代码分析工具:PyChecker、Pylint

# 安装pip install pylint
Salin selepas log masuk

写一段测试代码,命名为test.py

# -*- coding:utf-8 -*-# 原理:http://blog.csdn.net/morewindows/article/details/6684558# 代码提供: http://www.cnblogs.com/yekwol/p/5778040.htmldef parttion(vec, left, right):
    key = vec[left]
    low = left
    high = right    while low < high:        while (low < high) and (vec[high] >= key):
            high -= 1
        vec[low] = vec[high]        while (low < high) and (vec[low] <= key):
            low += 1
        vec[high] = vec[low]
        vec[low] = key    return low# 采用递归的方式进行函数构建def quicksort(vec, left, right):
    if left < right:
        p = parttion(vec, left, right)
        quicksort(vec, left, p-1)  # 再同样处理分片问题
        quicksort(vec, p+1, right)  
    return vec#s = [6, 8, 1, 4, 3, 9, 5, 4, 11, 2, 2, 15, 6]before_list = [4, 6, 1, 3, 5, 9]print "before sort:", before_list
after_list = quicksort(before_list, left=0, right=len(before_list)-1)print"after sort:", after_list
Salin selepas log masuk

进行代码规范测试

# 使用pylint test.py# 输出Problem importing module variables.py: No module named functools_lru_cache
Problem importing module variables.pyc: No module named functools_lru_cache
No config file found, using default configuration
************* Module test
C: 24, 0: Trailing whitespace (trailing-whitespace)
C:  1, 0: Missing module docstring (missing-docstring)
C:  5, 0: Missing function docstring (missing-docstring)
C: 20, 0: Missing function docstring (missing-docstring)
C: 22, 8: Invalid variable name "p" (invalid-name)
C: 28, 0: Invalid constant name "before_list" (invalid-name)
C: 30, 0: Invalid constant name "after_list" (invalid-name)


Report
======23 statements analysed.

Statistics by type
------------------

+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |1      |1          |=          |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |0      |0          |=          |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|method   |0      |0          |=          |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|function |2      |2          |=          |0.00        |0.00     |
+---------+-------+-----------+-----------+------------+---------+Raw metrics-----------

+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |23     |71.88 |23       |=          |
+----------+-------+------+---------+-----------+
|docstring |0      |0.00  |0        |=          |
+----------+-------+------+---------+-----------+
|comment   |5      |15.62 |5        |=          |
+----------+-------+------+---------+-----------+
|empty     |4      |12.50 |4        |=          |
+----------+-------+------+---------+-----------+Duplication-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |0        |=          |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000    |=          |
+-------------------------+------+---------+-----------+Messages by category--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |7      |7        |=          |
+-----------+-------+---------+-----------+
|refactor   |0      |0        |=          |
+-----------+-------+---------+-----------+
|warning    |0      |0        |=          |
+-----------+-------+---------+-----------+
|error      |0      |0        |=          |
+-----------+-------+---------+-----------+Messages--------

+--------------------+------------+
|message id          |occurrences |
+====================+============+
|missing-docstring   |3           |
+--------------------+------------+
|invalid-name        |3           |
+--------------------+------------+
|trailing-whitespace |1           |
+--------------------+------------+Global evaluation-----------------Your code has been rated at 6.96/10 (previous run: 6.96/10, +0.00)
Salin selepas log masuk


Python奇技淫巧


使用 Counter 进行计数统计

>>> from collections import Counter>>> Counter(s=3, c=2, e=1, u=1)
Counter({&#39;s&#39;: 3, &#39;c&#39;: 2, &#39;u&#39;: 1, &#39;e&#39;: 1})>>> some_data=(&#39;c&#39;, &#39;2&#39;, 2, 3, 5, &#39;c&#39;, &#39;d&#39;, 4, 5, &#39;d&#39;, &#39;d&#39;)>>> Counter(some_data).most_common(2)
[(&#39;d&#39;, 3), (&#39;c&#39;, 2)]>>> some_data=[&#39;c&#39;, &#39;2&#39;, 2, 3, 5, &#39;c&#39;, &#39;d&#39;, 4, 5, &#39;d&#39;, &#39;d&#39;]>>> Counter(some_data).most_common(2)
[(&#39;d&#39;, 3), (&#39;c&#39;, 2)]>>> some_data={&#39;c&#39;, &#39;2&#39;, 2, 3, 5, &#39;c&#39;, &#39;d&#39;, 4, 5, &#39;d&#39;, &#39;d&#39;}>>> Counter(some_data).most_common(2)
[(&#39;c&#39;, 1), (3, 1)]
Salin selepas log masuk


enumerate获取键值对

  • 在同时需要index和value值的时候可以使用 enumerate。下列分别将字符串,数组,列表与字典遍历序列中的元素以及它们的下标

>>> for i,j in enumerate(&#39;abcde&#39;):...     print i,j... 0 a1 b2 c3 d4 e>>> for i,j in enumerate([1,2,3,4]):...     print i,j... 0 11 22 33 4>>> for i,j in enumerate([1,2,3,4],start=1):...     print i,j... 1 12 23 34 4
Salin selepas log masuk

# 通过键索引来追踪元素
from collections import defaultdict

s = "the quick brown fox jumps over the lazy dog"words = s.split()
location = defaultdict(list)for m, n in enumerate(words):
    location[n].append(m)print location

# defaultdict(<type &#39;list&#39;>, {&#39;brown&#39;: [2], &#39;lazy&#39;: [7], &#39;over&#39;: [5], &#39;fox&#39;: [3],
# &#39;dog&#39;: [8], &#39;quick&#39;: [1], &#39;the&#39;: [0, 6], &#39;jumps&#39;: [4]})
Salin selepas log masuk


os.path的使用

  • os.path.join用于拼接路径,好处是可以根据系统自动选择正确的路径分隔符”/”或”\”

  • os.path.split 把路径分割成dirname和basename,返回一个元组

  • os.listdir 获取路径下所有文件,返回list

import os
path=os.path.abspath("ams8B.zip")print path  # /Users/didi/Desktop/testhelp/ams8B.zip  # 实际上该文件夹下没有ams8B.zipprint os.path.join("/".join(path.split("/")[:-1]),&#39;ams8B.gz&#39;)  # /Users/didi/Desktop/testhelp/ams8B.gzprint os.path.join("home","user","test")  # home/user/test# 把路径分割成dirname和basename,返回一个元组,作用在于不用区别到底是&#39;\&#39;还是&#39;/&#39;print os.path.split(path)  # (&#39;/Users/didi/Desktop/testhelp&#39;, &#39;ams8B.zip&#39;)print os.path.join(os.path.split(path)[0],&#39;ams8B.gz&#39;)  #   /Users/didi/Desktop/testhelp/ams8B.gzprint os.getcwd()  # /Users/didi/Desktop/testhelpprint os.listdir(os.getcwd())  # [&#39;t1.txt&#39;, &#39;test1.py&#39;, &#39;test2.py&#39;, &#39;\xe6\x8e\xa5\xe9\xa9\xbeeta\xe5\x88\x86\xe5\xb8\x83.sh&#39;]
Salin selepas log masuk

善用列表推导式

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]>>> print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]
>>>>>> print map(lambda x: x * 2 + 10, foo)
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>>>>> print reduce(lambda x, y: x + y, foo)139
Salin selepas log masuk

使用列表推导式

>>> [x * 2 + 10 for x in foo]
[14, 46, 28, 54, 44, 58, 26, 34, 64]>>> [x for x in foo if x % 3 == 0]
[18, 9, 24, 12, 27]
Salin selepas log masuk

对于轻量级循环,可尽量使用列表推导式,熟练使用列表推导式可以很多情况下代替map,filter等

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]>>> foo
[2, 18, 9, 22, 17, 24, 8, 12, 27]>>> [&#39;>3&#39; if i>3 else &#39;<3&#39; for i in foo]
[&#39;<3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;]>>> t=map(lambda x:&#39;<3&#39; if x<3 else &#39;>3&#39;,foo)>>> t
[&#39;<3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;, &#39;>3&#39;]
>>>
Salin selepas log masuk

可参考:最简单的理解lambda,map,reduce,filter,列表推导式


sort 与 sorted

# 函数原型sorted(iterable[, cmp[, key[, reverse]]])   # 返回一个排序后的列表s.sort([cmp[, key[, reverse]]])             # 直接修改原列表,返回为None>>> persons = [{&#39;name&#39;: &#39;Jon&#39;, &#39;age&#39;: 32}, {&#39;name&#39;: &#39;Alan&#39;, &#39;age&#39;: 50}, {&#39;name&#39;: &#39;Bob&#39;, &#39;age&#39;: 23}]>>> sorted(persons, key=lambda x: (x[&#39;name&#39;], -x[&#39;age&#39;]))
[{&#39;name&#39;: &#39;Alan&#39;, &#39;age&#39;: 50}, {&#39;name&#39;: &#39;Bob&#39;, &#39;age&#39;: 23}, {&#39;name&#39;: &#39;Jon&#39;, &#39;age&#39;: 32}]>>> a = (1, 2, 4, 2, 3)>>> sorted(a)
[1, 2, 2, 3, 4]>>> students = [(&#39;john&#39;, &#39;A&#39;, 15), (&#39;jane&#39;, &#39;B&#39;, 12), (&#39;dave&#39;, &#39;B&#39;, 10),]  
>>> sorted(students, key=lambda student : student[2])   # sort by age  [(&#39;dave&#39;, &#39;B&#39;, 10), (&#39;jane&#39;, &#39;B&#39;, 12), (&#39;john&#39;, &#39;A&#39;, 15)]
Salin selepas log masuk

所以如果实际过程中需要保留原有列表,可以使用sorted()。sort()不需要复制原有列表,消耗内存较小,效率较高。同时传入参数key比传入参数cmp效率要高,cmp传入的函数在整个排序过程中会调用多次,而key针对每个元素仅作一次处理。

关于cmp的使用,这位哥们总算踩到点python中sort()方法自定义cmp PythonTip-最大正整数

# cmp   --如果排序的元素是其他类型的,如果a逻辑小于b,函数返回负数;a逻辑等于b,函数返回0;a逻辑大于b,函数返回正数就行了,这决定着两者是否交换位置def Reverse(a,b):
    return b-a

list_ = [5,3,4,1,2]
new = sorted(list_,cmp=ps)print new  # [5, 4, 3, 2, 1]# # 这里的例子是,5,3做差值,为负,故两者不交换位置,里面的return作为条件
Salin selepas log masuk

善用traceback 追踪深层错误

import tracebacktry:
    do somethingexcept Exception as ex:    print ex
    traceback.print_exc()
Salin selepas log masuk

切片操作[]

相当于浅copy的作用

>>> a=[1,2,3]>>> b=a[:]>>> b.append(4)>>> b
[1, 2, 3, 4]>>> a
[1, 2, 3]>>> import copy>>> c=copy.copy(a)>>> c
[1, 2, 3]>>> c.append(4)>>> a
[1, 2, 3]>>> c
[1, 2, 3, 4]>>> d=a>>> d.append(4)>>> d
[1, 2, 3, 4]>>> a
[1, 2, 3, 4]# 这里顺便说下deepcopy# [理论部分可以参考这里](http://www.cnblogs.com/wait123/archive/2011/10/10/2206580.html)# 浅copy>>> import copy>>> a = [[1,2],3,4]>>> b = copy.copy(a)  
>>> id(a)54936008L>>> id(b)54964680L>>> a is bFalse>>> b
[[1, 2], 3, 4]>>> b[0][1]2>>> b[0][1]=2333>>> b
[[1, 2333], 3, 4]>>> a
[[1, 2333], 3, 4]# deepcopy>>> a = [[1,2],3,4]>>> c = copy.deepcopy(a)>>> id(a)55104008L>>> id(c)54974536L>>> a is cFalse>>> c
[[1, 2], 3, 4]>>> c[0][1]2>>> c[0][1]=233>>> c
[[1, 233], 3, 4]>>> a
[[1, 2], 3, 4]  # 不会随之改变# 这里测试下切片操作相当于浅copy>>> d = a[:]>>> d
[[1, 2], 3, 4]>>> d[0][1]=0>>> d
[[1, 0], 3, 4]>>> a
[[1, 0], 3, 4]  # 会随之改变
Salin selepas log masuk

进行逆序排列

>>> b
[1, 2, 3, 4]>>> b[::-1]
[4, 3, 2, 1]
Salin selepas log masuk

json.dump()/loads() 存储字典结构

# json.dumps : dict转成str # json.loads:str转成dictimport json
dict_ = {1:2, 3:4, "55":"66"}
json_str = json.dumps(dict_)print type(json_str), json_str 
# <type &#39;str&#39;> {"55": "66", "1": 2, "3": 4}print type(json.loads(json_str)) 
# <type &#39;dict&#39;> {u&#39;55&#39;: u&#39;66&#39;, u&#39;1&#39;: 2, u&#39;3&#39;: 4}
Salin selepas log masuk

pprint打印结构

from pprint import pprint
data = [(1,{&#39;a&#39;:&#39;A&#39;,&#39;b&#39;:&#39;B&#39;,&#39;c&#39;:&#39;C&#39;,&#39;d&#39;:&#39;D&#39;}),

        (2,{&#39;e&#39;:&#39;E&#39;,&#39;f&#39;:&#39;F&#39;,&#39;g&#39;:&#39;G&#39;,&#39;h&#39;:&#39;H&#39;,            &#39;i&#39;:&#39;I&#39;,&#39;j&#39;:&#39;J&#39;,&#39;k&#39;:&#39;K&#39;,&#39;l&#39;:&#39;L&#39;

            }),]print data
pprint(data)#print效果[(1, {&#39;a&#39;: &#39;A&#39;, &#39;c&#39;: &#39;C&#39;, &#39;b&#39;: &#39;B&#39;, &#39;d&#39;: &#39;D&#39;}), (2, {&#39;e&#39;: &#39;E&#39;, &#39;g&#39;: &#39;G&#39;, &#39;f&#39;: &#39;F&#39;, &#39;i&#39;: &#39;I&#39;, &#39;h&#39;: &#39;H&#39;, &#39;k&#39;: &#39;K&#39;, &#39;j&#39;: &#39;J&#39;, &#39;l&#39;: &#39;L&#39;})]# pprint效果[(1, {&#39;a&#39;: &#39;A&#39;, &#39;b&#39;: &#39;B&#39;, &#39;c&#39;: &#39;C&#39;, &#39;d&#39;: &#39;D&#39;}),
 (2,
  {&#39;e&#39;: &#39;E&#39;,   &#39;f&#39;: &#39;F&#39;,   &#39;g&#39;: &#39;G&#39;,   &#39;h&#39;: &#39;H&#39;,   &#39;i&#39;: &#39;I&#39;,   &#39;j&#39;: &#39;J&#39;,   &#39;k&#39;: &#39;K&#39;,   &#39;l&#39;: &#39;L&#39;})]
Salin selepas log masuk

zip打包元组

定义:zip([seql, …])接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list(列表)。若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同。

#!/usr/bin/python# -*- coding: utf-8 -*-name = [&#39;mrlevo&#39;,&#39;hasky&#39;]
kind = [&#39;human&#39;,&#39;dog&#39;]
z1 = [1,2,3]
z2 = [4,5,6]
result = zip(z1,z2) # 压缩过程uzip= zip(*result) # 解压过程,拆分为元组print "the zip:",result# the zip: [(1, 4), (2, 5), (3, 6)]print "the uzip:",uzip#the uzip: [(1, 2, 3), (4, 5, 6)]print "the uzip part of z1:%s\nthe uzip part of z2:%s"%(str(uzip[0]),str(uzip[1]))#the uzip part of z1:(1, 2, 3)#the uzip part of z2:(4, 5, 6)
Salin selepas log masuk

*args和**kw

*args仅仅只是用在函数定义的时候用来表示位置参数应该存储在变量args里面。Python允许我们制定一些参数并且通过args捕获其他所有剩余的未被捕捉的位置。当调用一个函数的时候,一个用*标志的变量意思是变量里面的内容需要被提取出来然后当做位置参数被使用。

def add(x, y):
    return x + y
list_ = [1,2]

add(list_[0], list_[1]) # 3add(*list_) # 3
Salin selepas log masuk

*args要么是表示调用方法大的时候额外的参数可以从一个可迭代列表中取得,要么就是定义方法的时候标志这个方法能够接受任意的位置参数。接下来提到的**,**kw代表着键值对的字典,也就是说,你不用一个个字典用key来取value了

dict_ = {&#39;x&#39;: 1, &#39;y&#39;: 2, &#39;z&#39;:3}def bar(x, y, z):
    return x + y + z

bar(**dict_)  # 6bar(dict_[&#39;x&#39;],dict_[&#39;y&#39;],dict_[&#39;z&#39;])  # 6
Salin selepas log masuk

内建函数 itertools优雅的迭代器

方法很多,就先介绍笔试题碰到的permutations

permutations(p[,r]);返回p中任意取r个元素做排列的元组的迭代器
如:permutations(‘abc’, 2) # 从’abcd’中挑选两个元素,比如ab, bc, … 将所有结果排序,返回为新的循环器。

注意,上面的组合分顺序,即ab, ba都返回。

combinations(‘abc’, 2) # 从’abcd’中挑选两个元素,比如ab, bc, … 将所有结果排序,返回为新的循环器。

注意,上面的组合不分顺序,即ab, ba的话,只返回一个ab。

再来个实际点的算法的一个例子,虽然毫无算法结构可言

# 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba# itertools,内建库的用法# 参考:http://blog.csdn.net/neweastsun/article/details/51965226import itertoolsdef Permutation(ss):
    # write code here
    if not ss:        return []    return sorted(list(set(map(lambda x:&#39;&#39;.join(x), itertools.permutations(ss)))))

Permutation(&#39;abc&#39;)# [&#39;abc&#39;, &#39;acb&#39;, &#39;bac&#39;, &#39;bca&#39;, &#39;cab&#39;, &#39;cba&#39;]
Salin selepas log masuk

更多可以参考:Python标准库13 循环器 (itertools)


使用with open() as f 来读取文件

对于文本的读取,使用f=open(‘path’)的方法来说,局限性很大,第一是内存加载问题,第二是文件流打开之后最后还需要关闭的问题,使用with..as轻松解决

with open(&#39;path&#39;) as f:    for line in f:
        do songthing# for line in f 这种用法是把文件对象f当作迭代对象,系统将自动处理IO缓存和内存管理。对于读取超大的文件,这个方法不会把内存撑爆,这个是按行读取的with open(&#39;path&#39;) as f:    for line in f.readlines():
        do something# 这个方法是将文本中的内容都放在了一个列表里,然后进行迭代,对于大量的数据而言,效果不好
Salin selepas log masuk

使用yield节省内存开销

[1,2,3,4]这个是迭代器,用for来迭代它,生成器(x for x in range(4))也是迭代器的一种,但是你只能迭代它们一次.原因很简单,因为它们不是全部存在内存里,它们只在要调用的时候在内存里生成,Yield的用法和关键字return差不多,下面的函数将会返回一个生成器。迭代的时候碰到yield立刻return一个值,下一次迭代的时候,从yield的下一条语句开始执行

>>> mygenerator = (x*x for x in range(4))>>> mygenerator
<generator object <genexpr> at 0x1121b55a0>>>> mygenerator.next()0>>> mygenerator.next()1---------------------->>> def generater(n):...     for i in range(n):...         yield i...         print &#39;here&#39;...>>> g = generater(5)>>> g
<generator object generater at 0x10c801280> # 凡是带有yield的函数都变成了生成器,都可以被迭代next()使用,>>> g.next()0>>> g.next()
here1>>> g.next()
here2 # 这里说明了它的运作过程,第一次迭代的时候,运行到yield函数,进行返回,而不执行下一个动作,第二次迭代的时候,直接从上一次yield的地方的下一条语句进行执行,也就看到了如下的效果。
Salin selepas log masuk

另一个 yield 的例子来源于文件读取。如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取:

# from 廖雪峰def read_file(fpath):
    BLOCK_SIZE = 1024
    with open(fpath, &#39;rb&#39;) as f:        while True:
            block = f.read(BLOCK_SIZE)           
             if block:                
            yield block            
            else:                
            return
Salin selepas log masuk

相关推荐:

Python安装流程指南


Atas ialah kandungan terperinci Python 常用的PEP8规范及Python小把戏 . Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk mengintegrasikan perkhidmatan Node.js atau Python dengan cekap di bawah seni bina lampu? Bagaimana untuk mengintegrasikan perkhidmatan Node.js atau Python dengan cekap di bawah seni bina lampu? Apr 01, 2025 pm 02:48 PM

Ramai pemaju laman web menghadapi masalah mengintegrasikan perkhidmatan node.js atau python di bawah seni bina lampu: lampu sedia ada (Linux Apache MySQL PHP) Laman web seni bina memerlukan ...

Apakah sebabnya mengapa fail penyimpanan berterusan saluran paip tidak dapat ditulis apabila menggunakan crawler scapy? Apakah sebabnya mengapa fail penyimpanan berterusan saluran paip tidak dapat ditulis apabila menggunakan crawler scapy? Apr 01, 2025 pm 04:03 PM

Apabila menggunakan crawler scapy, sebab mengapa fail penyimpanan berterusan paip tidak boleh ditulis? Perbincangan Ketika belajar menggunakan Crawler Scapy untuk Crawler Data, anda sering menemui ...

Apakah sebabnya mengapa Pool Proses Python mengendalikan permintaan TCP serentak dan menyebabkan pelanggan terjebak? Apakah sebabnya mengapa Pool Proses Python mengendalikan permintaan TCP serentak dan menyebabkan pelanggan terjebak? Apr 01, 2025 pm 04:09 PM

Proses Python Pool mengendalikan permintaan TCP serentak yang menyebabkan pelanggan terjebak. Apabila menggunakan Python untuk pengaturcaraan rangkaian, adalah penting untuk mengendalikan permintaan TCP serentak dengan cekap. …

Bagaimana untuk melihat fungsi asal yang terkandung secara dalaman oleh python funcools.partial Object? Bagaimana untuk melihat fungsi asal yang terkandung secara dalaman oleh python funcools.partial Object? Apr 01, 2025 pm 04:15 PM

Sangat meneroka kaedah tontonan python funcools.partial Object in Funcools.Partial Menggunakan Python ...

Pembangunan Aplikasi Desktop Cross-Platform Python: Perpustakaan GUI mana yang terbaik untuk anda? Pembangunan Aplikasi Desktop Cross-Platform Python: Perpustakaan GUI mana yang terbaik untuk anda? Apr 01, 2025 pm 05:24 PM

Pilihan Perpustakaan Pembangunan Aplikasi Desktop Python Python Banyak pemaju Python ingin membangunkan aplikasi desktop yang boleh dijalankan pada kedua-dua sistem Windows dan Linux ...

Python Hourglass Graph Lukisan: Bagaimana untuk mengelakkan kesilapan yang tidak ditentukan? Python Hourglass Graph Lukisan: Bagaimana untuk mengelakkan kesilapan yang tidak ditentukan? Apr 01, 2025 pm 06:27 PM

Bermula dengan Python: Lukisan Grafik Hourglass dan Pengesahan Input Artikel ini akan menyelesaikan masalah definisi berubah -ubah yang dihadapi oleh pemula python dalam program lukisan grafik Hourglass. Kod ...

Bagaimana cara mengira dan menyusun set data produk yang besar di Python? Bagaimana cara mengira dan menyusun set data produk yang besar di Python? Apr 01, 2025 pm 08:03 PM

Penukaran dan Statistik Data: Pemprosesan yang cekap bagi set data besar Artikel ini akan memperkenalkan secara terperinci bagaimana untuk menukar senarai data yang mengandungi maklumat produk kepada yang lain yang mengandungi ...

Bagaimana untuk menyelesaikan masalah kebenaran yang dihadapi semasa melihat versi Python di Terminal Linux? Bagaimana untuk menyelesaikan masalah kebenaran yang dihadapi semasa melihat versi Python di Terminal Linux? Apr 01, 2025 pm 05:09 PM

Penyelesaian kepada Isu Kebenaran Semasa Melihat Versi Python di Terminal Linux Apabila anda cuba melihat versi Python di Terminal Linux, masukkan Python ...

See all articles