Halcom 发表于 2019-9-18 22:54:30

PEP8规范

PEP8规范(欢迎大家补充&改正)(1)每一级缩进使用4个空格。(2)空格是首选的缩进方式。(3)制表符只能用于与同样使用制表符缩进的代码保持一致。(4)Python3不允许同时使用空格和制表符的缩进。(5)所有行限制的最大字符数为79。(6)Python标准库比较保守,需要将行宽限制在79个字符(文档/注释限制在72)。(7)类里的方法定义用一个空行隔开。(8)Python核心发布版本中的代码总是以UTF-8格式编码(或者在Python2中用ASCII编码)。(9)导入应该按照以下顺序分组:         a)标准库导入         b)相关第三方库导入         c)本地应用/库特定导入(10)避免通配符的导入(from import *),因为这样做会不知道命名空间中存在哪些名字,会使得读取接口和许多自动化工具之间产生混淆。(11)标准库要避免使用复杂的包引入结构,而总是使用绝对路径。(12)在Python中,单引号和双引号字符串是相同的。(13)避免在尾部添加空格。因为尾部的空格通常都看不见,会产生混乱;(14)与代码相矛盾的注释比没有注释还糟,当代码更改时,优先更新对应的注释!(15)注释应该是完整的句子。如果一个注释是一个短语或句子,它的第一个单词应该大写,除非它是以小写字母开头的标识符(永远不要改变标识符的大小写!)。如果注释很短,结尾的句号可以省略。块注释一般由完整句子的一个或多个段落组成,并且每句话结束有个句号。在句尾结束的时候应该使用两个空格。(16)有节制地使用行内注释。(17)永远不要使用字母‘l’(小写的L),‘O’(大写的O),或者‘I’(大写的I)作为单字符变量名。在有些字体里,这些字符无法和数字0和1区分,如果想用‘l’,用‘L’代替。(18)模块应该用简短全小写的名字,如果为了提升可读性,下划线也是可以用的。Python包名也应该使用简短全小写的名字,但不建议用下划线。当使用C或者C++编写了一个依赖于提供高级(更面向对象)接口的Python模块的扩展模块,这个C/C++模块需要一个下划线前缀(例如:_socket)。(19)类名一般使用首字母大写的约定。在接口被文档化并且主要被用于调用的情况下,可以使用函数的命名风格代替。因为异常一般都是类,所有类的命名方法在这里也适用。然而,你需要在异常名后面加上“Error”后缀(如果异常确实是一个错误)。全局常量全部大写,可以加下划线;(20)函数名应该小写,如果想提高可读性可以用下划线分隔。   始终要将 self 作为实例方法的的第一个参数。   始终要将 cls 作为类静态方法的第一个参数。   如果函数的参数名和已有的关键词冲突,在最后加单一下划线比缩写或随意拼写更好。因此 class_ 比 clss 更好。(也许最好用同义词来避免这种冲突)(21)公共属性不应该有前缀下划线。对于单一的共有属性数据,最好直接对外暴露它的变量名,而不是通过负责的存取器(accessor)/突变(mutator) 方法。(22)任何向后兼容保证只适用于公共接口,因此,用户清晰地区分公共接口和内部接口非常重要。(23)两种情况不应该只使用‘excpet’块:       如果异常处理的代码会打印或者记录log;至少让用户知道发生了一个错误。       如果代码需要做清理工作,使用 raise..try…finally 能很好处理这种情况并且能让异常继续上浮。(24)使用字符串方法代替字符串模块。字符串方法总是更快,并且和unicode字符串分享相同的API。如果需要兼容Python2.0之前的版本可以不用考虑这个规则。

参考:【1】PEP8规范






Halcom 发表于 2019-9-22 11:45:00

isinstance函数
      Python提供isinstance函数判断变量的数据类型,类似type(),具体如下:
>>> isinstance(2, int)
True
>>> isinstance(2, str)
False
>>> isinstance(2, float)
False
>>> isinstance(2.3, str)
False
>>> isinstance(2.3, float)
True
>>>      掌握这些内容后,读者可以很简便的操作数据类型了。
lambda函数使用:使用lambda来创建匿名函数
      通常我们的函数定义如下:
>>> def fun(x):
...   return x*x-2*x+1;
...
>>> fun(1)
0
>>> fun(2)
1
>>>
      Python提供了简单的lambda函数可供使用,具体如下:
>>> ys = lambda x: x*x-2*x+1;
>>> ys(1)
0
>>> ys(2)
1
>>>      lambda作为关键字函数位于变量x的前面。
filter函数使用:返回True结果
      filter函数用于刷选用户定义的数据,具体的使用帮助如下:
>>> help(filter)
Help on built-in function filter in module __builtin__:

filter(...)
    filter(function or None, sequence) -> list, tuple, or string
   
    Return those items of sequence for which function(item) is true.If
    function is None, return the items that are true.If sequence is a tuple
    or string, return the same type, else return a list.      filter函数支持list,tuple和string类型数据的使用,那么具体的使用方法怎么样呢?我们先用简单的函数表示如下:
def odd(x):
    return x%2;
ys = ;
y = filter(odd, ys)
>>> y
      首先程序定义了一个odd(x)函数,该函数的目的是,如果x是偶数则返回0,如果x是奇数,则返回1。通过filter函数,刷选ysw数组里面存在的的奇数。
      当然,我们在这里也可以用lambda函数进行刷选ysw里面的奇数,具体如下:
>>> ys = ;
>>> y = filter(lambda x:x%2, ys)
>>> y
      为了更加直观的理解filter函数,我们修改函数表达式,具体如下:
>>> ys = ;
>>> y = filter(lambda x:x*2, ys)
>>> y
      当x%2改为x*2后,那么filter函数第一个输入项全部大于0,则直接返回ysw的每一个数值,非零项将不返回,具体使用如下:
>>> ys = ;
>>> y = filter(lambda x:x*2, ys)
>>> y
map映射函数
      我们看下面的代码:
>>> ys = ;
>>> y = filter(lambda x:x*2, ys)
>>> y
      我们以为x*2就会得到ysw里面的每一个元素都乘以2的结果,其实返回的是过滤了非零项的元素值,那么我们怎么才能得到x*2的全部数值呢?
      Python提供了map函数,将数组每个数值进行运算,得到一个全新的数组,具体如下:
>>> ys = ;
>>> y = map(lambda x:x%2, ys)
>>> y

>>> y = map(lambda x:x*2, ys)
>>> y

>>>dir()函数
dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。
dir语法:
dir()参数说明:object -- 对象、变量、类型。
返回值:返回模块的属性列表。
dir()
Out:
['In', 'Out', '_', '_3', '_4', '_5', '__', '___', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dh', '_exit_code', '_i', '_i1', '_i2', '_i3', '_i4', '_i5', '_i6', '_i7', '_ih', '_ii', '_iii',
'_oh', 'exit', 'get_ipython', 'quit', 's']

dir([])
Out: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append',
'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

dir(list)
Out: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']assert函数
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
assert false, 'blabla'
# 如果条件不成立,则打印出 'blabla' 并抛出AssertionError异常具体的使用方法如下:
>>> assert True   # 条件为 true 正常执行
>>> assert False    # 条件为 false 触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> assert 1==1    # 条件为 true 正常执行
>>> assert 1==2    # 条件为 false 触发异常
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError

>>> assert 1==2, '1 不等于 2'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: 1 不等于 2raise函数
Python 使用 raise 语句抛出一个指定的异常。
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
raise NameError('HiThere')
Traceback (most recent call last):

File "<ipython-input-32-72c183edb298>", line 1, in <module>
    raise NameError('HiThere')

NameError: HiThere你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:
class MyError(Exception):
      def __init__(self, value):
            self.value = value
      def __str__(self):
            return repr(self.value)
try:
    raise MyError(2*2)
except MyError as e:
    print('My exception occurred, value:', e.value)
   
My exception occurred, value: 4输入其它数据:
raise MyError('python')
Traceback (most recent call last):

File "<ipython-input-41-a6c3b9d9766c>", line 1, in <module>
    raise MyError('python')

MyError: 'python'
try……excepttry………except
一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
# 可写函数说明
def this_fails():
    x = 1/0
try:
    this_fails()
except ZeroDivisionError as err:
    print('Handling run-time error:', err)
Handling run-time error: division by zero一个except子句可以同时处理多个异常。
except (RuntimeError, TypeError, NameError):
      passtry except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。
try……finally说明
不管 try 子句里面有没有发生异常,finally 子句都会执行。
>>>def divide(x, y):
      try:
            result = x / y
      except ZeroDivisionError:
            print("division by zero!")
      else:
            print("result is", result)
      finally:
            print("executing finally clause")
   
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str's含义
s代表的意思是列表s中的第i个元素(包含), 到第j个元素(不包含),每隔k个数取一个 形成的列表:
s=['ydgf','sdf','ddfhfh','fsgdfhh', 'gfdgh']
print(s)
['sdf', 'fsgdfhh']注释符
"""
Created on Mon Sep 16 22:31:38 2019

@author: ys
"""运算符
//:取整除 - 返回商的整数部分(向下取整)
7//3
Out: 2
**:幂 - 返回x的y次幂
2**3
Out: 8
*:乘 - 两个数相乘或是返回一个被重复若干次的字符串
print('6'*3)
666
2*3
Out: 6不可更改(immutable)对象
python中,strings, tuples, 和numbers是不可更改的对象,list,dict等则是可以修改的对象。
def ChangeInt( a ):
    a = 10
   
b = 2
ChangeInt(b)
print( b ) # 结果是 2
2可更改(mutable)对象
python中,strings, tuples, 和numbers是不可更改的对象,list,dict等则是可以修改的对象。
# 可写函数说明
def changeme( mylist ):
   "修改传入的列表"
   mylist.append()
   print ("函数内取值: ", mylist)
   return

# 调用changeme函数
mylist =
changeme( mylist )
print ("函数外取值: ", mylist)
函数内取值:]
函数外取值:]如果输入:
# 调用changeme函数
mylist = []
changeme( mylist )
print ("函数外取值: ", mylist)
函数内取值:[]
函数外取值:[]如果输入:
# 可写函数说明
def changeme( mylist ):
   "修改传入的列表"
   mylist.append([])
   print ("函数内取值: ", mylist)
   return

# 调用changeme函数
mylist =
changeme( mylist )
print ("函数外取值: ", mylist)
函数内取值:]
函数外取值:]排序法时间复杂度和空间复杂度
类别               排序法            时间复杂度          空间复杂度            性能          备注
                桶排序               O(m+n)                O(m+n)               稳定          年龄的范围为1-120,此时就可以开辟120个桶进行统计排序
                哈希桶排序      O(m+n)               O(m+n)               稳定          哈希桶因子(hashFactor):hashFactor = (max - min) / length
交换排序      冒泡排序         O(n2)                      O(1)                  稳定          n小时较好
交换排序      快速排序         O(n*log2n)      O(log2n)~O(n)      不稳定      n大时较好,时间复杂度最小O(n*log2n)
选择排序      选择排序         O(n2)                     O(1)                  不稳定      n小时较好
选择排序      堆排序             O(nlogn)               O(1)                   不稳定      n大时较好
       插入排序                  O(n2)                     O(1)                  稳定      大部分已排序时较好
       归并排序                   O(nlogn)                  O(n)                  稳定      n大时较好
使用 pdb进行调试
命令                         解释
break 或 b            设置断点      设置断点
continue 或 c      继续执行程序
list 或 l               查看当前行的代码段
step 或 s            进入函数
return 或 r            执行代码直到从当前函数返回
exit 或 q               中止并退出
next 或 n            执行下一行
pp                     打印变量的值
help                     帮助
二叉树
前序遍历:根左右。先打印,再遍历左子树,再遍历右子树;
中序遍历:左根右。先遍历左子树,再打印,再遍历右子树;
后序遍历:左右根。先遍历左子树,再遍历右子树,再打印。
已知前序遍历和后序遍历,无法确定一颗唯一的二叉树。
例子:知道中序和后序遍历,画二叉树和写出前序遍历:
      已知中序遍历是:HDMIBJNEAFKCG,后续遍历是HMIDNJEBKFGCA,写出前序遍历。
从后序遍历知道,最后一个必然是根节点,因此A是根。再结合中序遍历可知HDMIBJNE是A的左子树部分,FKCG是右子树部分。

取A的右子树部分来看先,右子树部分的中序遍历:FKCG,后序遍历:KFGC。接着从后序遍历中看A的右子树部分KFGC,所以C是根。又从中序遍历知,FK是C的左子树部分,G是C右子树。如图所示。

使用同样的方法,C的左子树部分,中序:FK,后序:KF。可以得出F是根,那么K只能是F的右子树了。此时如图所示,A的右子树部分都出来了。

……
哈希桶
桶排序:简单的理解为:例如需要对一个公司的员工的年龄进行排序,年龄的范围为1-120,此时就可以开辟120个桶进行统计排序。
哈希桶排序法则使用了用哈希函数对序列进行划分,哈希函数把序列划分到对应的桶里面,最后使用其它的排序算法或者递归使用哈希排序进行排序从而得到一个整体有序的序列。
设有数组 array = ,那么数组中最大数为 49,先设置 5 个桶,那么每个桶可存放数的范围为:09、1019、2029、3039、40~49,然后分别将这些数放人自己所属的桶,如下图:

哈希桶因子(hashFactor):hashFactor = (max - min) / length。
设有数组 array = ,那么数组中最大值max = 10011,最小值min = 1,哈希桶因子hashFactor = (10011 - 1) / 10 = 1001。对数组进行划分,10011 / 1001 = 10,所以10011放在keywei10的桶里面;10001 / 1001 = 9, 所以10001放在key为9的桶里面,以此类推,最后得到的桶的情况为:{0=, 9=, 10=}。再分别对每个桶进行排序即可。
print & format耗时对比
import time
start_time = time.time()
for i in range(1000):
    print('%s' % 'xi'+'gua')
   
elapse_time = time.time() - start_time
print(elapse_time)

start_time = time.time()
for i in range(1000):
    print('{0} {1}'.format('xi','gua'))# 带数字编号

elapse_time2 = time.time() - start_time
print(elapse_time2)

start_time = time.time()
for i in range(1000):
    print('%s %s' % ('xi','gua'))

elapse_time3 = time.time() - start_time
print(elapse_time3)输出:
print(elapse_time)
0.1280074119567871

print(elapse_time2)
0.4240243434906006

print(elapse_time3)
0.3780217170715332      打印的%s越少越好,越少越快。format耗时较严重;       使用字符串方法代替字符串模块。字符串方法总是更快
二进制转换
                  2进制                                       8进制                                       10进制                               16进制
2进制                -                                       bin(int(x, 8))                              bin(int(x, 10))                  bin(int(x, 16))
8进制          oct(int(x, 2))                                 -                                        oct(int(x, 10))                  oct(int(x, 16))
10进制      int(x, 2):2进制到10进制          int(x, 8):8进制到10进制                     -                              int(x, 16):16进制到10进制
16进制      hex(int(x, 2))                           hex(int(x, 8))                              hex(int(x, 10))                         -
例如:
int('1011',2)
Out: 11链表
(1)删除排序链表中的重复元素
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3
答题代码如下:
# Definition for singly-linked list.
# class ListNode:
#   def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
      if head is None:
            return None
      pre = ListNode(-100000)
      pre.next = head
      slow = pre
      fast = pre.next
      while fast :
            if slow.val == fast.val:
                fast = fast.next
                slow.next = fast
            else:
                slow = slow.next
                fast = fast.next
      return pre.next
(2)合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
答题代码如下:
# Definition for singly-linked list.
# class ListNode:
#   def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
      l3 = ListNode(-1);
      l4 = l3;
      if not l1:
            return l2
      if not l2:
            return l1
      while(l1 is not None and l2 is not None):
            if(l1.val<l2.val):
                l4.next = l1
                l1=l1.next
            else:
                l4.next = l2
                l2=l2.next
            l4 = l4.next
      if(l1 is None):
            l4.next = l2
      else:
            l4.next = l1
      return l3.next




Halcom 发表于 2019-9-22 12:27:11

动态分配内存:
s = input()
a = []
for i in s:
    if 0 <= ord(i) <= 127 and i not in a:
      a.append(i)
print(len(a))s = input()
d = {}
for i in s:
    if 0 <= ord(i) <= 127:
      d = 1
print(sum(d.values()))
页: [1]
查看完整版本: PEP8规范