当前位置:   article > 正文

【python】 程序设计基础_python程序设计基础

python程序设计基础

总结

python 默认变量都是字符串

配置

数据源

C:\Users\Jarvis\AppData\Roaming\pip -> pip.ini
Jarvis是用户名

阿里云数据源不如清华源

[global]
timeout = 10000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
  • 1
  • 2
  • 3

临时使用:
可以在使用pip的时候在后面加上-i参数,指定pip源
pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple

数据类型

表2-4 Python的标量

数值类型

Python的主要数值类型是intfloatint可以存储任意大的数

In [48]: ival = 17239871

In [49]: ival ** 6
Out[49]: 26254519291092456596965462913230729701102721
  • 1
  • 2
  • 3
  • 4

浮点数使用Python的float类型。每个数都是双精度(64位)的值。也可以用科学计数法表示:

In [50]: fval = 7.243

In [51]: fval2 = 6.78e-5
  • 1
  • 2
  • 3

不能得到整数的除法会得到浮点数

In [52]: 3 / 2
Out[52]: 1.5
  • 1
  • 2

要获得C-风格的整除(去掉小数部分),可以使用底除运算符//:

In [53]: 3 // 2
Out[53]: 1
  • 1
  • 2

序列函数

enumerate

迭代一个序列时,你可能想跟踪当前项的序号。手动的方法可能是下面这样:

i = 0
for value in collection:
   # do something with value
   i += 1
  • 1
  • 2
  • 3
  • 4

因为这么做很常见,Python内建了一个enumerate函数,可以返回(i, value)元组序列:

for i, value in enumerate(collection):
   # do something with value
  • 1
  • 2

当你索引数据时,使用enumerate的一个好方法是计算序列(唯一的)dict映射到位置的值:

In [83]: some_list = ['foo', 'bar', 'baz']

In [84]: mapping = {}

In [85]: for i, v in enumerate(some_list):
   ....:     mapping[v] = i

In [86]: mapping
Out[86]: {'bar': 1, 'baz': 2, 'foo': 0}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

sorted函数

sorted函数可以从任意序列的元素返回一个新的排好序的列表

In [87]: sorted([7, 1, 2, 6, 0, 3, 2])
Out[87]: [0, 1, 2, 2, 3, 6, 7]

In [88]: sorted('horse race')
Out[88]: [' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's']
  • 1
  • 2
  • 3
  • 4
  • 5

sorted函数可以接受和sort相同的参数。

zip函数

zip可以将多个列表、元组或其它序列成对组合成一个元组列表

In [89]: seq1 = ['foo', 'bar', 'baz']

In [90]: seq2 = ['one', 'two', 'three']

In [91]: zipped = zip(seq1, seq2)

In [92]: list(zipped)
Out[92]: [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

zip可以处理任意多的序列,元素的个数取决于最短的序列

In [93]: seq3 = [False, True]

In [94]: list(zip(seq1, seq2, seq3))
Out[94]: [('foo', 'one', False), ('bar', 'two', True)]
  • 1
  • 2
  • 3
  • 4

zip的常见用法之一是同时迭代多个序列,可能结合enumerate使用:

In [95]: for i, (a, b) in enumerate(zip(seq1, seq2)):
   ....:     print('{0}: {1}, {2}'.format(i, a, b))
   ....:
0: foo, one
1: bar, two
2: baz, three
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

给出一个“被压缩的”序列,zip可以被用来解压序列。也可以当作把行的列表转换为列的列表。这个方法看起来有点神奇:

In [96]: pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'),
   ....:             ('Schilling', 'Curt')]

In [97]: first_names, last_names = zip(*pitchers)

In [98]: first_names
Out[98]: ('Nolan', 'Roger', 'Schilling')

In [99]: last_names
Out[99]: ('Ryan', 'Clemens', 'Curt')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

reversed函数

reversed可以从后向前迭代一个序列:

In [100]: list(reversed(range(10)))
Out[100]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
  • 1
  • 2

要记住reversed是一个生成器(后面详细介绍),只有实体化(即列表或for循环)之后才能创建翻转的序列。

输入

【参考:python技巧2:用input同时输入多个数_graysu的博客-CSDN博客

a,b =input('输入a,b空格隔开:').split()
#此时a,b为str型

a,b =map(int,input('输入a,b空格隔开:').split())
#此时a,b为int型

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

多行字符串格式化输出

【参考:textwrap — Text wrapping and filling — Python 3.11.0 documentation

import textwrap

# \ 是格式化换行
# 缩进要一致
str1 = """\
    name:{},
    sex:{},
    age:{},
""".format('Jack', 18,'man' )

print(textwrap.dedent(str1)) # 删除文本中每一行中任何常见的前导空格。
"""
name:Jack,
sex:18,
age:man,
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

错误例子

 """\
name:{},
	sex:{},
    age:{}
"""

"""\
    name:{},
sex:{},
    age:{}
"""
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

输出

In [74]: template = '{0:.2f} {1:s} are worth US${2:d}'
  • 1

在这个字符串中,

  • {0:.2f}表示格式化第一个参数为带有两位小数的浮点数。
  • {1:s}表示格式化第二个参数为字符串。
  • {2:d}表示格式化第三个参数为一个整数。

要替换参数为这些格式化的参数,我们传递format方法一个序列:

In [75]: template.format(4.5560, 'Argentine Pesos', 1)
Out[75]: '4.56 Argentine Pesos are worth US$1'
  • 1
  • 2

【参考:Python输出函数print总结(python print())_THEAQING-CSDN博客

print(*objects, sep=' ', end='\n', file=sys.stdout)

参数的具体含义如下:

objects --表示输出的对象。输出多个对象时,需要用 , (逗号)分隔。

sep -- 用来间隔多个对象。

end -- 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符。

file -- 要写入的文件对象。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

【参考:python - 输入输出 之 字符串前缀u、r、b、f含义_开码河粉-CSDN博客

r:转义无效符
在字符串前加r使当前字符串的转义字符无效,按原样输出


print(u"江西") # 江西

print(r'\n hello \v') # \n hello \v
# 字符串变量
s='\n hello \v'
print(repr(s))# \n hello \v

s=r"123\n123\n"
print(s)
print(type(s))
print(repr(s))
print(type(repr(s)))

'''
123\n123\n
<class 'str'>
'123\\n123\\n'
<class 'str'>
'''


# Python3.6新加特性
account='myaijarvis'
month=12
print(f'我的微信公众号是:{account},已经连续发文{int(month) * 5}天啦!')
# 我的微信公众号是:myaijarvis,已经连续发文60天啦!

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

【参考:Python repr函数_全村的希望的博客-CSDN博客


python 数值类型只有 int(整形)、float(浮点型,3.x提供17位有效小数,相当于C语言的double)、complex(复数型)

r = (85-72) / 72  *100
print(r)
print('%.1f%%'%r) # %% -> %
print(f'{r:.1f}%') # f'{变量:格式说明符}'
print('{0:.1f}%'.format(r))

print(1/3)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
18.055555555555554
18.1%
18.1%
18.1%
0.3333333333333333
  • 1
  • 2
  • 3
  • 4
  • 5

复合数据类型

list

list是一种有序的集合

arr=[]
arr.append(1)
arr.append(2)
arr.append(3)
arr.append(4)
for i in range(0,len(arr)):
    print(arr[i],end=' ')#  1 2 3 4
print()

arr.pop() # 删除4
arr.pop(1) # 删除下标为1的数,即数字2
arr.insert(0, 5) # 在下标为0的位置插入5

for a in arr:
    print(a,end=' ')# 5 1 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

tuple

tuple和list非常类似,但是tuple一旦初始化就不能修改

t=() # 空元组
t=(1,) # 一个元素的元组
  • 1
  • 2

dict

【参考:使用dict和set - 廖雪峰的官方网站
dict的key必须是不可变对象

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}

print(d['Michael']) # 95
print(d.get('Bob')) # 75
print(d.get('Jack')) # None
print(d.get('Jack',-1)) # 设置默认值-1

d.setdefault('Tom',100) # 添加元素

d.pop('Tracy') # 删除元素

for k,v in d.items():
    print(k,v)
    
for i in d:
    print("%s:%s"%(i,d[i]))
    
'''    
Michael 95
Bob 75
Tom 100
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

和list比较,dict有以下几个特点:

  • 查找和插入的速度极快(哈希算法),不会随着key的增加而变慢;
  • 需要占用大量的内存,内存浪费多。

而list相反:

  • 查找和插入的时间随着元素的增加而增加;
  • 占用空间小,浪费内存很少。
    所以,dict是用空间来换取时间的一种方法。

set

s = {'Michael' ,'Bob','Tracy'}

s.add('Jack') # 添加

s.remove('Tracy') # 删除

for k in s:
    print(k)
'''
Michael
Jack
Bob
'''
s_null=set() # 空集合

print(len(s_null)) # 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

数字

在这里插入图片描述

bool

    	False   	True
int 	00
float	0.00.0
str		'' 空字符串	非空字符串

列表	[] 空列表
元组	() 
字典	{}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

日期和时间

Python内建的datetime模块提供了datetimedatetime类型。datetime类型结合了datetime,是最常使用的:

In [102]: from datetime import datetime, date, time

In [103]: dt = datetime(2011, 10, 29, 20, 30, 21)

In [104]: dt.day
Out[104]: 29

In [105]: dt.minute
Out[105]: 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

根据datetime实例,你可以用datetime提取出各自的对象:

In [106]: dt.date()
Out[106]: datetime.date(2011, 10, 29)

In [107]: dt.time()
Out[107]: datetime.time(20, 30, 21)
  • 1
  • 2
  • 3
  • 4
  • 5

strftime方法可以将datetime格式化为字符串:

In [108]: dt.strftime('%m/%d/%Y %H:%M')
Out[108]: '10/29/2011 20:30'
  • 1
  • 2

strptime可以将字符串转换成datetime对象:

In [109]: datetime.strptime('20091031', '%Y%m%d')
Out[109]: datetime.datetime(2009, 10, 31, 0, 0)
  • 1
  • 2

表2-5列出了所有的格式化命令。

表2-5 Datetime格式化指令(与ISO C89兼容)

当你聚类或对时间序列进行分组,替换datetimes的time字段有时会很有用。例如,用0替换分和秒:

In [110]: dt.replace(minute=0, second=0)
Out[110]: datetime.datetime(2011, 10, 29, 20, 0)
  • 1
  • 2

因为datetime.datetime是不可变类型,上面的方法会产生新的对象。

两个datetime对象的差会产生一个datetime.timedelta类型:

In [111]: dt2 = datetime(2011, 11, 15, 22, 30)

In [112]: delta = dt2 - dt

In [113]: delta
Out[113]: datetime.timedelta(17, 7179)

In [114]: type(delta)
Out[114]: datetime.timedelta
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

结果timedelta(17, 7179)指明了timedelta将17天、7179秒的编码方式。

timedelta添加到datetime,会产生一个新的偏移datetime

In [115]: dt
Out[115]: datetime.datetime(2011, 10, 29, 20, 30, 21)

In [116]: dt + delta
Out[116]: datetime.datetime(2011, 11, 15, 22, 30)
  • 1
  • 2
  • 3
  • 4
  • 5

高级特性 ***

切片

Python中符合序列的有序序列都支持切片(slice),例如列表,字符串,元组
格式:[start:end:step]
start:起始索引,从0开始,-1表示结束
end:结束索引
step:步长,end-start,步长为正时,从左向右取值步长为负时,反向取值
注意切片的结果不包含结束索引,即不包含最后的一位,-1代表列表的最后一个位置索引

【参考:切片 - 廖雪峰的官方网站

L = list(range(100))
print(L) # 1,2,3,....,99
print(L[-1]) # 99 倒数第一个元素的索引是-1
print(L[:5]) # [0, 1, 2, 3, 4] 前5个
print(L[-5:]) # [95, 96, 97, 98, 99] 后5个

# 只写[:]就可以原样复制一个list
L2=L[:] # 深复制
print(L2) 

# tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
t=(0, 1, 2, 3, 4, 5)
print(t[:3]) # (0, 1, 2)

# 字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串
s='ABCDEFG'
print(s[:3]) # 'ABC'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

反向 ***

[i:j:k] 其中k<0

=> [n+i:n+j:k] 默认[-1:-n-1:k]
比如[0:n:1] 中间的为0+n=n ; [-1:-n-1:k] 中间的为 -1 + -n = -n-1
最右边编号为-1,索引范围为-n到-1 ,-n即第一个

a='123456'
print(a[::-1]) 
# 默认 print(a[-1:-len(a)-1:-1]) # 默认 -len(a)-1=-7 相当于字符1的前面一个 -6指向字符1

print(a[0::-1])
print(a[1::-1])
print(a[2::-1]) # 从下标为2的元素翻转读取

654321
654321
1
21
321
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

下面好像有点错误 以后再说

s='Hello World!'
s[-1:-5:-1] # !dlr
  • 1
  • 2
a=[1,2,3,4,5,6]

b1=a[:] #省略全部,代表截取全部内容,可以用来将一个列表拷给另一个列表(深拷贝)
print(b1)
结果:[1, 2, 3, 4, 5, 6]

b=a[0:-1:1] #从位置0开始到结束,每次增加1,截取。不包含结束索引位置,-1代表最后一个位置
print(b)
结果:[1, 2, 3, 4, 5]

==================
[:end]
c1=a[:3] #省略起始位置的索引,以及步长。默认起始位置从头开始,默认步长为1,结束位置索引为3
print(c1)
结果:[1, 2, 3]
==================

c=a[0:5:3] #从第一个位置到第6个位置,每3个取一个值
print(c)
结果:[1, 4]

d=a[5:0:-1] #反向取值
print(d)
结果:[6, 5, 4, 3, 2]

d1=a[::-1]
print(d1)
结果:[6, 5, 4, 3, 2, 1]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

迭代

【参考:迭代 - 廖雪峰的官方网站

如何判断一个对象是可迭代对象呢?方法是通过collections.abc模块的Iterable类型判断:

from collections.abc import Iterable

print(isinstance('abc', Iterable))  # str是否可迭代
# True
print(isinstance([1, 2, 3], Iterable))  # list是否可迭代
# True
print(isinstance(123, Iterable))  # 整数是否可迭代
# False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

for i, value in enumerate(['A', 'B', 'C']):
    print(i, value)

0 A
1 B
2 C
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
for x, y in [(1, 1), (2, 4), (3, 9)]:
	print(x, y)

1 1
2 4
3 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

列表生成式

【参考:列表生成式 - 廖雪峰的官方网站

[x * x for x in range(1, 11)]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

[x * x for x in range(1, 11) if x % 2 == 0]
# [4, 16, 36, 64, 100]

# 全排列
[m + n for m in 'ABC' for n in 'XYZ']
# ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

import os # 导入os模块,模块的概念后面讲到
[d for d in os.listdir('.')] # os.listdir可以列出文件和目录
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

if … else

在一个列表生成式中,for前面的if … else是表达式,而for后面的if是过滤条件,不能带else

[x for x in range(1, 11) if x % 2 == 0]
# [2, 4, 6, 8, 10]

[x if x % 2 == 0 else -x for x in range(1, 11)]
# [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
  • 1
  • 2
  • 3
  • 4
  • 5

生成器

【参考:生成器 - 廖雪峰的官方网站
一边循环一边计算的机制,称为生成器:generator

其创建方式为,把列表推导式两端的方括号改成圆括号

g = (x * x for x in range(10))  # 注意,这里是圆括号
print(g)  # <generator object <genexpr> at 0x000001E584F361B0> generator也是可迭代对象

print(next(g))  # 每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素

for n in g:
    print(n)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return 'done'

'''
t = (b, a + b) # t是一个tuple
a = t[0]
b = t[1]
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator:

调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
f = fib(6)
f # <generator object fib at 0x104feaaa0>

for n in fib(6):
	print(n)

1
1
2
3
5
8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

yield

https://www.cnblogs.com/ellisonzhang/p/10273843.html
简要理解:yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。

迭代器

【参考:迭代器 - 廖雪峰的官方网站
我们已经知道,可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

可以使用isinstance()判断一个对象是否是Iterable对象:

>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

可以使用isinstance()判断一个对象是否是Iterator对象:

>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
  • 1
  • 2
  • 3
  • 4

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

函数式编程

高阶函数

【参考:高阶函数 - 廖雪峰的官方网站

让函数的参数能够接收别的函数

def add(x, y, f):
    return f(x) + f(y)
  • 1
  • 2

map

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回

>>> def f(x):
...     return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

reduce

reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

常常与map一起使用

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

# 求和
>>> from functools import reduce
>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

filter

Python内建的filter()函数用于过滤序列。

和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

def is_odd(n):
    return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
  • 1
  • 2
  • 3
  • 4
  • 5

sorted

>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]

>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
# 分别按名字排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_name(t):
	return t[0].lower()
L2 = sorted(L, key=by_name)
print(L2)

# 用成绩来进行排序,成绩由高到低

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_score(t):
    return t[1] # return -t[1] 下面就不用 reverse

L2 = sorted(L, key=by_score,reverse=True)
print(L2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

返回函数

【参考:返回函数 - 廖雪峰的官方网站

返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

def count():
    fs = []
    for i in range(1, 4):

        def f():
            return i * i

        fs.append(f)
    return fs  # 返回一个列表,里面三个数


f1, f2, f3 = count()  # 列表自动会给三个变量赋值
# 此时就已经运行count()函数了,然后i=3了

print(f1())  # 9
print(f2())  # 9
print(f3())  # 9

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:

def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs
再看看结果:

>>> f1, f2, f3 = count()
>>> f1()
1
>>> f2()
4
>>> f3()
9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

匿名函数

>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
  • 1
  • 2

通过对比可以看出,匿名函数lambda x: x * x实际上就是:

def f(x):
    return x * x
  • 1
  • 2

匿名函数有个限制,就是只能有一个表达式不用写return,返回值就是该表达式的结果。

匿名函数也是一个函数对象,利用lambda作为返回值时,得到的是一个函数,而不是一个值。

装饰器

【参考:装饰器 - 廖雪峰的官方网站
decorator被称为装饰模式

还不是很理解

偏函数

【参考:偏函数 - 廖雪峰的官方网站


  • 1

模块

【参考:安装第三方模块 - 廖雪峰的官方网站
模块搜索路径
当我们试图加载一个模块时,Python会在指定的路径下搜索对应的.py文件,如果找不到,就会报错:

>>> import mymodule
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mymodule
  • 1
  • 2
  • 3
  • 4

默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:

>>> import sys
>>> sys.path
['c:\\Users\\Jarvis\\Desktop\\Code\\py', 
'C:\\anaconda3\\python37.zip',
'C:\\anaconda3\\DLLs', 
'C:\\anaconda3\\lib', 
'C:\\anaconda3', 
'C:\\Users\\Jarvis\\AppData\\Roaming\\Python\\Python37\\site-packages', 
'C:\\anaconda3\\lib\\site-packages', 
'C:\\anaconda3\\lib\\site-packages\\win32', 'C:\\anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\anaconda3\\lib\\site-packages\\Pythonwin']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果我们要添加自己的搜索目录,有两种方法:

一是直接修改sys.path,添加要搜索的目录:

>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')
  • 1
  • 2

这种方法是在运行时修改,运行结束后失效

第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。

面向对象编程

类和实例

【参考:类和实例 - 廖雪峰的官方网站

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'
            
lisa = Student('Lisa', 99)
bart = Student('Bart', 59)
print(lisa.name, lisa.get_grade())
print(bart.name, bart.get_grade())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

访问限制

【参考:访问限制 - 廖雪峰的官方网站

继承和多态

【参考:继承和多态 - 廖雪峰的官方网站

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

获取对象信息

【参考:获取对象信息 - 廖雪峰的官方网站
基本类型都可以用type()判断:
isinstance()可以告诉我们,一个对象是否是某种类型

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:

仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:

>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

实例属性和类属性

【参考:实例属性和类属性 - 廖雪峰的官方网站

实例属性属于各个实例所有,互不干扰;

类属性属于类所有,所有实例共享一个属性;

给实例绑定属性的方法是通过实例变量,或者通过self变量:

class Student(object):
    def __init__(self, name):
        self.name = name

s = Student('Bob')
s.score = 90
但是,如果Student类本身需要绑定一个属性呢?可以直接在class中定义属性,这种属性是类属性,归Student类所有:

class Student(object):
    name = 'Student'
当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
>>> class Student(object):
...     name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性.

面向对象高级编程 wait

错误、调试和测试

错误处理

【参考:错误处理 - 廖雪峰的官方网站
https://docs.python.org/3/library/exceptions.html#exception-hierarchy

调试

【参考:调试 - 廖雪峰的官方网站

凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:

def foo(s):
    n = int(s)
    assert n != 0, 'n is zero!'
    return 10 / n

def main():
    foo('0')
assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

单元测试 wait

【参考:单元测试 - 廖雪峰的官方网站

文档测试 wait

【参考:文档测试 - 廖雪峰的官方网站

IO编程 wait

文件读写

【参考:文件读写 - 廖雪峰的官方网站

with语句来自动帮我们调用close()方法

StringIO和BytesIO

【参考:StringIO和BytesIO - 廖雪峰的官方网站
StringIO顾名思义就是在内存中读写str。
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO

操作文件和目录

【参考:操作文件和目录 - 廖雪峰的官方网站

序列化

【参考:序列化 - 廖雪峰的官方网站

进程和线程 wait

【参考:进程和线程 - 廖雪峰的官方网站

正则表达式 wait

【参考:正则表达式 - 廖雪峰的官方网站
【参考:正则表达式 - 廖雪峰的官方网站

常用内建模块 wait

【参考:常用内建模块 - 廖雪峰的官方网站

collections ***

常用第三方模块 ***

【参考:常用第三方模块 - 廖雪峰的官方网站

字典(Dictionary)

items()

dict = {'Google': 'www.google.com', 'Runoob': 'www.runoob.com', 'taobao': 'www.taobao.com'}
 
print "字典值 : %s" %  dict.items()
 
# 遍历字典列表
for key,values in  dict.items():
    print key,values

字典值 : [('Google', 'www.google.com'), ('taobao', 'www.taobao.com'), ('Runoob', 'www.runoob.com')]
Google www.google.com
taobao www.taobao.com
Runoob www.runoob.com
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

字符串

字符串是一个序列的Unicode字符,因此可以像其它序列,比如列表和元组(下一章会详细介绍两者)一样处理:

In [64]: s = 'python'

In [65]: list(s)
Out[65]: ['p', 'y', 't', 'h', 'o', 'n']
  • 1
  • 2
  • 3
  • 4

join()

'separtor'.join(sequence)

参数说明
separtor:分隔符。可以为空
sequence:要连接的元素序列、字符串、元组、字典
上面的语法即:以separtor作为分隔符,将sequence所有的元素合并成一个新的字符串

返回值:返回一个以分隔符sep连接各个元素后生成的字符串

实例:
seq3 = ('hello','good','boy','doiido')
print(':'.join(seq3)) # hello:good:boy:doiido

data={
    "id":1000,
    "name":"Jack",
    "age":18
}
keys=",".join(data.keys())
print(keys) # id,name,age
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

文件操作

with open() as f

https://blog.csdn.net/MsSpark/article/details/86745391

with open'filename.txt','r',encode='utf-8') as f:
   data_user=pd.read_csv(f)  #文件的读操作

with open('data.txt','w',encode='utf-8') as f:
   f.write('hello world')  #文件的写操作
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

file对象属性

file.read([size])   将文件数据作为字符串返回,可选参数size控制读取的字节数
file.readlines([size])   返回文件中行内容的列表,size参数可选
file.write(str)   将字符串写入文件
file.writelines(strings)   将字符串序列写入文件
file.close()   关闭文件
file.closed	表示文件已经被关闭,否则为False

file.mode	Access文件打开时使用的访问模式
file.encoding	文件所使用的编码
file.name	文件名
file.newlines	未读取到行分隔符时为None,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束的列表
file.softspace	为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性一般程序员用不着,由程序内部使用
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

函数

定义函数

【参考:定义函数 - 廖雪峰的官方网站

如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。return None可以简写为return

数据类型检查可以用内置函数isinstance()实现

def my_abs(x):
    if not isinstance(x, (int,float())):
        raise TypeError('类型有误')
    if x>=0:
        return x;
    elif x<0:
        return -x;
    
print(my_abs(-1)) # 1
print(my_abs('x'))

1
Traceback (most recent call last):
  File "c:\Users\Jarvis\Desktop\Code\py\demo.py", line 10, in <module>
    print(my_abs('x'))
  File "c:\Users\Jarvis\Desktop\Code\py\demo.py", line 2, in my_abs
    if not isinstance(x, (int,float())):
TypeError: isinstance() arg 2 must be a type or tuple of types
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    # 在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值
    return nx, ny 

x, y = move(100, 100, 60, math.pi / 6)
print(x, y) # 151.96152422706632 70.0

r = move(100, 100, 60, math.pi / 6)
print(r) # (151.96152422706632, 70.0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

函数的参数

【参考:函数的参数 - 廖雪峰的官方网站

一是必选参数在前,默认参数在后,否则Python的解释器会报错
默认参数必须指向不变对象

也可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。比如调用enroll(‘Adam’, ‘M’, city=‘Tianjin’),意思是,city参数用传进去的值,其他默认参数继续使用默认值。

def enroll(name, gender, age=6, city='Beijing'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)
    
    
enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

可变参数

# 在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple
def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum
    
# 调用该函数时,可以传入任意个参数,包括0个参数
calc() # 0
calc((1,2,3)) # 6

nums = [1, 2, 3]
calc(*nums) # *nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

装饰器 待理解

在这里插入图片描述
在这里插入图片描述

call

只要定义类型的时候,实现__call__函数,这个类型就成为可调用的
换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符

class Person():
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
    def __call__(self, friend):
        print('My name is %s...' % self.name)
        print('My friend is %s...' % friend)

B = Person('Jack','male')
B('Mark')

output:
My name is Jack
My friend is Mark
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

1.from 包名 import 函数名

from datatime import datatime
datetime.now()



2.import 函数名

import datetime
datetime.datetime.now() 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述

OS

在这里插入图片描述
在这里插入图片描述

path

在这里插入图片描述
在这里插入图片描述

system

在这里插入图片描述
在这里插入图片描述

数据库操作

MySQL

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/783117
推荐阅读
相关标签
  

闽ICP备14008679号