初识Python(v3.9)
内含与C/C++、Java的类比和对比
[by_041]
文章目录
基本概述
本内容基本上就是相较于C\C++的观点
其中C\C++的基本运算符大都被Python很好的保留甚至优化了
个人感觉弱化了语句的概念,代码写起来更像命令集
不同点有以下:
内容 Before After 真假常数 true
、false
True
、False
或None
逻辑运算 &&
、||
、!
and
、or
、not
无返回值类型 void NoneType Python的类与对象的处理方式和Java极其相似(毕竟其底层是Java)
Tips
-
在Python中
''
和""
含义一样 -
注释:
# 行注释 ''' 语段注释 '''
-
Python对空格、回车和Tab十分敏感,格式要注意了
- 空格和Tab直接代替了
{}
行首的缩进情况表示层次,同一个层次中的语句相当于C\C++中被{}
括号括起来了
- 空格和Tab直接代替了
-
实践证明:精度损失依然存在!!但是,其用了某种方法【我猜是数据扰动】减小了在运行中精度损失对整体的影响
输入输出
输出
- 标准输出:
print()
输出所有参数,最后换行 - 参数表:
参数 | 含义 | 默认 | 注意 |
---|---|---|---|
end=’’ | 输出结尾=’’ | 回车 | 只能在末尾加入【不包括同类标识符,下同】 |
sep=’.’ | 参数间间隔=’.’ | 空格 | 只能在末尾加入 |
-
还有格式化输出:
#(类似C的printf) print("格式化字符串"%变量) print("格式化字符串"%(变量1,变量2,…)) # 有点C++的cout流的味道 print("这是变量1:{}\n这是变量2:{}\n这是变量3:{}\n".format(a1, a2, a3)) print("{:.6f}".format(float(a)))
格式化字符 含义 %c 字符 %s 字符串,通过str()字符串转换来格式化 %i 有符号十进制整数 %d 有符号十进制整数 %u 无符号十进制整数 %o 八进制整数 %x、%X 十六进制整数 %e、%E 索引符号 %f 浮点实数 %g、%G %f、%e的简写 %% 输出百分号,%.2f%%
输入:
-
input()
:输出()
中的内容(只允许存在一个参数),然后读取一行字符返回其组成的字符串# 同行输入: a,b=input().split() a,b=map(int,input().split()) # 如果有更多变量只需: a,b,c=input().split() a,b,c=map(int,input().split()) # 用逗号隔开: a,b,c=input().split(',') a,b,c=map(int,input().split(',')) # 输入列表 a=input().split()
-
C\C++中
while(scanf(..)!=EOF){}
的操作可以写成:wangshu搭的例题# eg. A+B 输入输出练习I while True: try : a,b=map(int,input().split()) print(a+b) # 输入以及操作 except : break # 或者直接exit(0)
数据类型相关
基本内容
-
Python中的变量十分灵活
- 类型:
- 主要有:整数(int)、实数(float)、字符串(str)、列表(list)、元组(tuple)、字典(dict)
- 还包括:
- 等差参数(range):相当于用逗号隔开的一个参数集
- 无返回型(NoneType)
- 支持直接赋值:
a=1
、s=''
- 支持递增操作:
s+='.'
- 类型:
-
序列很强大!!!!
- eg.套娃:
[1,2,3,4,[1,2,3,4,[1,2,3,4],5],5]
- eg.套娃:
-
相关操作:
- 返回变量类型:
type(a)
- 强制类型转换:
int(a)
、float(a)
、str(a)
、list()
- 返回变量类型:
-
对象内存地址:
id(a)
-
运算符号:
-
字符串str类型可以进行
s1+s2
(在s1末尾追加s2的串)、s*a
(s重复a次的串)还有>\<\=\<=\>=
(字典序比较)操作 -
a**b
:次方,a的b次幂 -
a//b
:整除,向下取整 -
赋值运算符:
**=
、//=
[相较与C\C++增添的,++
、--
失效] -
成员运算符:
in
[a in b
返回a是否在序列b的元素中]、not in
-
身份运算符:
is
[id(a)==id(b)
是否引用了同一对象]、is not
-
运算符优先级:
运算符 描述 ** 指数(最高优先级) *、/、%、// 乘、除、取模、取整除 >>、<< 右移、左移(位运算) & 位’AND’ ^、| 位运算符 <=、<、>、>= 比较运算符 [没有<>、]==、 != 等于运算符 =、%=、/=、//=、-=、+=、*=、**= 赋值运算符 is、is not 身份运算符(相当于指针间的比较,下方列表的例子中有体现) in、not in 成员运算符 and、or、not(没有&&/||/!) 逻辑运算符
-
字符串’…’/"…"/…:
-
表示:[
''
或""
、'''...'''
或"""..."""
,其中'
和"
符号成对基本等价]-
和C\C++相同,用
""
括起来,或用和""
基本等价''
括起来# 差异在: print("I'm GOOD !") print('I\'m GOOD !') # 上面俩句等价,且只能这么写 print('I said "yes" ') print("I said \"yes\" ") # t同样,这个也是
-
新增
'''间隔几行'''
或"""间隔几行"""
,表示多行字符串print('''这里是第一行的内容 中间的内容1 中间的内容2 这里是最后一行''') print(‘End_by_041’) # 输出: # 这里是第一行的内容 # 中间的内容1 # 中间的内容2 # 这里是最后一行 # End_by_041 # [Finished in 0.1s]
-
常用的转义字符:
转义字符 描述 \ (在行尾时) 续行符【在打Py命令行的时候也能用这个续行】 \ \ 反斜杠 \ ’ 单引号 \ " 双引号 \a 响铃 \b 退格(BackSpace) \000 空 \n 换行 \v 纵向制表 \t 横向指标 \r 回车 \f 换页 \oyy 八进制数,yy代表的字符,换行 \xyy 十六进制yy代表字符,例如\x0a代表换行 \other 其他的字符以普通格式输出 -
成员函数:
- str_name.title():以首字母大写的方式显示单词
- upper():是以全部大写的方式显示字符串
- lower():是以全部小写的方式显示字符串
-
列表list[…]
list_name = [ element_1 , element_2 , element_3 , ... ]
存储方式有点像链表,但是强大到飞起
- 添加:
a.append(b)
:在列表a尾添加元素ba.insert(f,b)
:在列表a的f位置添加元素b,原来的f位置以及后面的元素后移
- 删除:
del a[b]
:删除列表a的第b号元素a.pop(b)
:删除列表a的第b号元素,并返回a[b]的值a.remove(b)
:删除列表a中值为b的第一个元素,不存在则啥也不干,甚至会报错,记得判断
- 排序:
a.sort()
:对列表a进行永久性排序,按照字母顺序a.sorted()
:对列表a进行临时性排序a.reverse()
:对列表a反转排序
- 属性:
len(a)
:确定长度
以下是列表list功能强大的部分体现,后续的内容中还有许多关于ta的操作、
# 代码
a=[[v for v in range(3)],10,(1,2),[[101],[123,321,[12,12]]]]
for i in a:
print(i)
# 运行结果:
# [0, 1, 2]
# 10
# (1, 2)
# [[101], [123, 321, [12, 12]]]
# 一个有趣的现象(这里类比Java)
x=y=[1,2,3]
print(x)
y[1]=0
print(x)
# Output:
# [1, 2, 3]
# [1, 0, 3]
元组tuple(…)
tuples_name = ( element_1 , element_2 , element_3 , ... )
元组可记忆为不可单独改变元素的列表,与列表的区别:列表用,而元组用
()
元组的元素不可更改,但是整体可以重新赋值,下面是个例子:
#打印结果为['hongqi', 'audi', 'toyata', 'subaru']
cars = ['bmw','audi','toyata','subaru']
cars[0] = 'hongqi'
print(cars)
#报错,元组的单个元素不可更改
cars=('bmw','audi','toyata','subaru')
cars[0]='hongqi'
print(cars)
#不会报错,输出结果为('hongqi', 'audi', 'toyata', 'subaru')
cars = ('bmw','audi','toyata','subaru')
cars = ('hongqi', 'audi', 'toyata', 'subaru')
print(cars)
字典
类比C++的STL库中的映射
<map>
借鉴的原文说:
字典类似于C\C++中的结构体class/struct,只不过是动态可变的,在初始定以后还能添加、修改、删除(del)属性值
我觉得不妥,这个字典应该更像是C++的STL库中的映射
<map>
,因为ta存储是数据到数据的对应关系Key:value的对应
,定义中每一项目的:
两端或调用时下标[]
中填写的都是数据,而不是结构体的引用成员,这两点是不一样的、
- 通过**items()**返回字典中的键-值对,并将其以列表形式存储下来,通过for循环能够遍历字典【实践见下框19行】
- 通过**keys()**函数能够返回所有字典中的键名字,并形成列表
- 通过**values()**函数能够获得字典中的值列表
- 将字典作为元素存储在列表里,或者将列表作为字典中的值存储在字典中,我们称之为嵌套;
- 还有一种方式是在字典中存储字典,不再详细展开。
person_me = {
'sex' : 'male',
'id' : 'Teloy_041',
20 : 'SH',
'doing' : ['blogging','coding']
}
print('\n','='*41,'type','='*41)
print(type(person_me))
print('\n','='*41,'dict','='*41)
print(person_me)
print('\n','='*41,'elements','='*41)
print('sex :',person_me['sex'])
print(' 20 :',person_me[20])
print('\n','='*41,'key - val','='*41)
for key, value in person_me.items():
print("\nkey :",key)
print("val :",value)
print('\n','='*41,'keys','='*41)
for key in person_me.keys():
print(key)
print('\n','='*41,'values','='*41)
for value in person_me.values():
print(value)
# 字典嵌套和列表嵌套类似,此处不再举例
print('\n','='*41,'ENDing','='*41)
# 运行结果:
# ========================================= type =========================================
# <class 'dict'>
#
# ========================================= dict =========================================
# {'sex': 'male', 'id': 'Teloy_041', 20: 'SH', 'doing': ['blogging', 'coding']}
#
# ========================================= elements =========================================
# sex : male
# 20 : SH
#
# ========================================= key - val =========================================
#
# key : sex
# val : male
#
# key : id
# val : Teloy_041
#
# key : 20
# val : SH
#
# key : doing
# val : ['blogging', 'coding']
#
# ========================================= keys =========================================
# sex
# id
# 20
# doing
#
# ========================================= values =========================================
# male
# Teloy_041
# SH
# ['blogging', 'coding']
#
# ========================================= ENDing =========================================
# [Finished in 0.1s]
类
就是正宗的class/struct
- 类中包含一个所描述对象的基本属性和一些方法(即类中的函数)
class Car():
#这里的初始化属性,__init__()的左右各两个下划线是一种约定,旨在避免方法与普通方法产生名称冲突
#self这个形参是自动传递的,记住就好,约定俗成
def __init__( self, maker, model, year ):
self.maker = maker
self.model = model
self.year = year
#类中的普通方法,形参一般为self
def get_descriptive_name( self ):
long_name = str(self.year) + ' ' + self.maker + ' ' + self.model
return long_name.title()
my_new_car = Car( 'audi', 'a4', 2019 )
print(my_new_car.get_descriptive_name())
- 属性值可以通过直接访问(即赋值)和类中的方法去更改;
- 继承是指在创建一个新的类时候,大多数属性可以用一个旧的类中的属性去描述,那么就可以用继承创建新类,只需要在 __init__模块中附属新的属性即可(需要注意的是创建子类时,父类必须包含在当前的文件中);
- 若父类的方法不适用于子类,则可以重写,即在子类中定义同名方法,那么python会忽略父类同名方法;
class Car():
# 这里的初始化属性,__init__()的左右各两个下划线是一种约定,旨在避免方法与普通方法产生名称冲突
# self这个形参是自动传递的,记住就好,约定俗成
def __init__(self, maker, model, year):
self.maker = maker
self.model = model
self.year = year
# 类中的普通方法,形参一般为self
def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.maker + ' ' + self.model
return long_name.title()
class ElectricCar(Car):
# 只需要包含电动汽车的新属性即可
def __init__(self, maker, model, year, battery_size):
# 用super()关联父类和子类
super().__init__(maker, model, year)
# 新属性
self.battery_size = battery_size
def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.maker + ' ' + self.model + ' ' + str( self.battery_size )
return long_name.title()
my_new_car = ElectricCar('audi', 'a4', 2019, 70)
print(my_new_car.get_descriptive_name())
- 当程序达到一定程度,需要从其他文件中导入类,方法和导入函数类似:
#这是导入一个类的模板
from module_name import object1_name
#这是导入两个类的模板,以此类推
from module_name import object1_name, object2_name
#这是导入一个模块所有类的模板
from module_name import *
类编码的方式需要注意:
- 类名的每个单词首字母用大写,并且不适用下划线
- 实例和模块名用小写格式,并在单词之间加上下划线
- 其余参照驼峰命名法
控制命令
注意上层语句后的
:
判断
-
if
if ???: ... elif ???: ... else: ...
循环
Python中的while()和for的功能就区分的很明确了
break、continue语句仍然适用
然后Python还多了一个占位语句(空语句)操作:
pass
然后循环之后可以加一个同一层次的**
else:
**以至少运行一次!!且比do-while好用也好理解多了!
-
while(条件循环)
i=1 while i<=10: print(i) i+=1 else: print(i) # 存在的意义:至少运行一次!!且比do-while好用也好理解多了!
-
for(遍历循环,按照下标)
# for的遍历,很像C++11的auto for i in range(5): # 遍历[0,,4] print(i) for a in [1,2,3,4]: # 遍历列表,a的类型是各个元素的类型 print(a) for c in "Hello!": # 遍历字符串,c的类型时str,是子串! print(c) # 因为是按照下标的 isp=list(range(11)) for a in isp: print("now :",a) if a*2 in isp: isp.remove(a*2) print('\tremove(%d)'%(a*2)) else: print(a) print('') for a in isp: print(a,end='') # 运行结果: # now : 0 # remove(0) # now : 2 # remove(4) # now : 3 # remove(6) # now : 5 # remove(10) # now : 7 # 7 # now : 8 # 8 # now : 9 # 9 # # 1235789 # [Finished in 0.1s]
函数
-
Python中的函数的定义长这样:
# 基本定义 def func_name(): pass return # ... # 描述完整的一种定义方式 def ret_itself(a:int)->int: return a print(type(depart())) # <class '函数数据类型'> # ...为空,或者无return的类型就是'NoneType'
-
再试试函数的自调用:
def depart(a): if(type(a)!=int or a<0): print('depart : dead') exit() print(a) if(a==0): return 0 return depart(a-1) print(type(depart(6))) print('='*41) print(type(depart('6')))
-
使用默认值时记得把有默认值的参数放在参数列表的末端(不然编译会出错)
-
同时传递的实参也可以是列表
-
不定参数:当传递多个数量,甚至任意数量的实参时,可以将函数形参设置为元组,那么无论实参有多少个,都可以封装到这个元组中,同样,要放到参数列表的末端
def make_pizza( *toppings ): print("\nMaking a pizza with following toppings:") print(toppings) make_pizza('mushrooms', 'green peppers', 'extra cheese')
-
在某些时候,我们在接受任意数量的实参时,不知道传递给函数,会是什么样的信息,可以在函数体内设置字典,将实参以键-值的形式存在字典内:
def build_profile( first, last, **user_info):
profile = {
}
profile['first'] = first
profile['last'] = last
for key, value in user_info.items():
profile[key] = value
return profile
- 以下是函数编写的一些规范:
- 函数名称应为描述性名称,且只使用小写字母和下划线;
- 注释中应该包括函数名称、需要的实参以及返回值类型;
进阶操作(更新ING!!!)
min(a,b,...) # 最小值
max(a,b,...) # 最大值
sum(a,b,...) # 求和,只针对数
str(...) # 将其中的参数转化为string类型
# 当list中的俩俩元素类型相同时可以直接在括号中写列表名求相应值
# 链表的切片,这部分的a、b都是大等0的整数
list_name[a:b] # 下标在[a,b]的元素组成的子序列
list_name[a:] # 下标a以及其之后的元素组成的子序列
list_name[:b] # 下标b以及其之前的元素促成的子序列
list_name[-a:] # 列表中的倒数a个元素所组成的子序列
list_name[:] # 同样表示列表中的所有元素组成的序列
range(begin,end,step) # 步长为step在[begin,end)的等差数列,参数一定要是整数(int),可正可负
range(begin,end) # 默认步长为1在[begin,end)的等差数列
range(a) # 从0开始的a个整数,[0,,a-1]!!
list(range(a)) # 生成[0,a)的整数列表
# 列表的解析:下面的例子是制作1~9的平方表
squares = [ value**2 for value in range(1,11) ]
# 相当于
# numbers = list(range(1,11))
# squares = []
#
# for number in numbers:
# squares.append(number**2)
# print(squares)
# =======================================
# 调库!!!以下是需要导入库的内容:
import random # 引入随机数库
x=random.randint(0,100) # 返回[a,b]范围内的随机整数,天生就是随机数呢!!
from time import perf_counter
print(perf_counter()) # 输出程序运行时间
样例程序
分解元组和列表的输出disintegrate_output.py
def disintegrate_output(a):
if(type(a)==list or type(a)==tuple):
for b in a:
disintegrate_output(b)
else:
print(a)
return
disintegrate_output((1,[2,3],4,(5,6)))
第n小质数
N_=10000
lsp=list(range(1,N_))
i=2
i_end=(N_+1)/2
while i<=i_end:
for j in lsp[2:]:
if(j>i):
break
va=i*j
if va in lsp:
lsp.remove(va)
else:
break
i+=1
# for i in lsp[1:]:
# print(i)
# print(len(lsp))
print(lsp[int(input())])
import
给你的Python注入灵魂的关键字
-
导入整个模块,或者将某个模块中的一个或多个函数导入:
import some_module from some_module import some_function # 可以定义成别名:as nickname from some_module import func_1,func_2,...
安装插件
-
在cmd命令窗输入:
安装: pip install 库名 更新 pip install --upgrade 库名
-
博主已安装:
lxml、 pyOpenSSL 、 Twisted 、pywin32、scrapy pillow√,matplotlib√,numpy√,pandas√,jieba√,wordcloud√,imagecodecs√ 等等一堆(漫长)
发文时才接触三天python,有不当之处请在评论区指出ha~
可能要过比较久了下次更新关键词:类、try语句
借鉴:CSND网址
【彩蛋】Python之禅
import this