欢迎访问我的GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

本篇概览

  • 欣宸是个Java程序员,最近正在学习Python,本文记录了学习过程,以及一点自己的思考,主要用途是作为笔记来总结和温习,另外如果您也是一位初学Python的Java程序员,希望本文能给您一些参考;

版本

操作系统:macOS Big Sur (11.6)

Anaconda3:2021.05

python:3.7.3

Jupyter Notebook:5.7.8

工具

  • 编辑器用的是Jupyter Notebook,以下三个快捷键最常用到,尤其是第三个,执行当前行,并新增一行:

  • 废话不多说了,直接开始动手操作;

除法

  • 一个斜杠的除法,结果是浮点型,两个斜杠的触发,结果是整形:

字符串

  • 格式化的时候,可以不指定参数索引,此时按照出现顺序处理:

  • 也可以在花括号中添加数字:

  • 还可以在花括号中添加冒号,在冒号之后添加特定的输出格式

  • 保留小数点后三位,f表示浮点数:

  • 带符号保留小数点后三位,f表示浮点数:

  • 不显示小数:

列表

  • 逗号分隔,方括号包裹:

  • 列表各个元素的类型无需相同(这一点和Java数组是不同的)

  • 访问列表中的元素,使用方括号+索引(从0开始):

  • 索引数值可以为负,负一表示倒数第一:

  • 与字符串的字符不同之处在于,列表的元素可以修改:

  • 分片,下面代码表示从0开始,一直取到2-1位置(左闭右开):

  • 分片的时候,冒号左边不填就表示从0开始,右边不填表示直到最后一个元素:

  • 分片可以接受第三个参数:步长,下面的表示每遍历两个元素才取一个

  • 当步长等于负一的时候,相当于反转了:

  • 用加号实现两个列表相连:

  • 列表乘以数字N,表示生成一个新的列表,内容是原列表的N份复制:

  • append:尾部追加元素

  • insert:将元素插入在指定位置

  • extend:将一个列表追加到另一个列表尾部

  • 方法id可以查看对象的内存地址,如下图,可见经历了append、insert、extend等操作后,内存地址不变,也就是说这些都是原地操作(in place):

列表的删除操作

  • 删除列表元素有三种方式:pop、remove、clear

  • pop()会弹出最后一个元素:

  • 也可以将索引作为入参传入,这样就能删除指定元素:

  • remove方法的入参是列表中的值,也就是找到列表中与入参相同的元素,将其删掉,下图可见,myList中有两个'abc',用remove会删除第一个:

  • clear方法会清空列表:

列表的记数和索引

  • count方法统计指定元素在列表中的数量,从下图可见1在列表中出现了两次:

  • index查找指定元素出现的位置:

列表排序

  • sort方法用来排序,默认是比较元素大小:

  • 默认是升序,添加reverse=True表示降序:

  • sort操作的是列表对象本身,还可以用全局函数sorted来排序,该函数会生成一个新的副本,如下图,newList是排序后的列表,而原有的myList保持不变:

与列表相关的常用全局函数

  • 除了sorted,还有一些常用的全局函数和列表有关:

  • operator(取代原有的cmp),用于比较大小以及是否相等:

  • len:计算个数

  • max:返回最大值

  • min:返回最小值

  • list:元组转为列表

  • zip:两个列表中,同位置元素结合成一个元组,最终得到一个元组列表:

  • enumerate:将指定列表的每个元素与其位置下表组成一个元组,最终得到一个元组列表(和上面的zip用法相似,不过简单多了,range操作已经在enumerate内部实现),如下图:

元组

  • 元组与列表相似,但是一旦创建就不能修改,创建使用的是圆括号(列表是方括号)

  • 要注意的是,只有一个元素的元组也要带逗号,例如(1,),这很好理解,毕竟(1)就是个整数而已

  • 没有括号,只有逗号,也是元组:

  • 下标操作和列表相同:

  • 列表转元组用tuple函数:

  • tuple函数还能将字符串直接转为元组:

  • 修改元组会失败:

  • 修改元组的思路是创建新的元组,如下图,用三个元组拼接的方式生成了一个新的元组,相比旧的,新元组的第三个元素已经从2变为'a',给人以修改过的感觉:

字典

  • 字典和Java的map相似,由多个键值对构成,键和值之间用冒号分隔,多个键值之间用逗号分隔,外面用大括号包裹:

  • 字典看起来很像json

  • items方法返回所有元素,keys返回所有键,values返回所有值:

  • 可以用键查找值,和Java的map一样,不过语法是中括号:

  • 也可以用get方法返回键对应的值,还能指定键不存在时的默认值:

  • 直接用方括号,可以修改,如果键不存在就是添加:

  • update方法的入参是另一个字典,该方法可以将入参字典的内容合并进自身:

  • pop方法删除指定元素,popitem方法删除最后一个元素:

集合(Set)

  • 提到Set,Java程序员应该不陌生,就是咱们经常用来排重的那个Set,是个无序元素集

  • 集合用逗号分隔,大括号包裹:

  • 小结三种包裹方式:列表方括号,元组圆括号,字典和集合大括号(字典的元素是键值对,集合是单个元素),另外元组可以不包裹,有逗号就行

  • set方法可以将列表转为集合:

  • 集合的元素都是不可变类型的,如数值、字符串、元组

  • 可变类型不能作为集合的元素,如列表、字典、集合,至于其中原因,看看下图红框的错误信息,如果您是个Java程序员,应该get到了:

  • 可以用减号或者difference方法求两个集合的差集:

程序逻辑控制

  • if判断,是用if、elif、else的组合,注意if、elif、else的行末尾都有冒号:

  • python不支持switch

  • if判断的三元操作符,赋值的时候可用if else组合:

  • 普通的for循环:

  • 内置函数range可以创建整数列表,也能在for循环中遍历:

  • while循环的语法和java相似:

  • 循环中的break和continue与Java类似,就不赘述了

推导式:列表

  • 格式如下:
[生成表达式 for 变量 in 序列或迭代对象]
  • 测试如下,a就是列表推导式生成的列表:

  • 还可以通过if增加筛选条件,例如下面是只保留偶数:

  • 如果列表的元素也是列表,我们可以用列表推导将其解开,平铺为一层,下图的例子中,a_element是a的元素,a_element自身也是列表,还可以用推导将其展开:

推导式:字典

  • 对字典用推导式,可以取得键和值的处理,下面是用推导式生成一个新的字典,剔除了键为age的键值对:

推导式:集合

  • 下面使用推导式,利用列表生成一个新集合,里面的值是原列表每个元素的平方,而且由于集合的不重复性,原列表中重复的元素已经被过滤为只剩一个:

导入库

  • 语法:
import 模块名 [as 别名]
  • 例如导入math模块来计算正弦值:

  • 如果觉得每次在代码中写math太麻烦,还可以在导入时设置别名:

  • 如果觉得别名也麻烦,能不能把m.也去掉,可以用以下语法:
from 模块名 import 对象名

例如:

  • 上述极简的方式是不推荐使用的,因为缺少了namespace隔离,在API的正确性上就缺少了保障

关于自己的模块

  • 假设有一个python文件hello.py,内容如下,定义了名为doHello的方法,再执行一下试试:
def doHello():
print("hello world!") doHello()
  • 现在另一个文件test.py,里面会调用hello.py中的doHello的方法:
import hello

hello()
  • 执行命令python test.py,结果如下,可见hello world!输出了两次:
will$ python test.py
hello world!
hello world!
  • 上述结果显然不是我们想要的,test.py只是想使用doHello方法,结果将hello.py中的doHello()也执行了,需要一种方式来避免test.py中的doHello()被执行

  • 这时候内置变量name就派上用场了(注意前后都是两个下划线),将hello.py改成如下内容,如果执行python hello.py,内置变量name的值就是main,其他时候,例如hello.py被其他文件import的时候,它的值就是模块名(这里就是hello):

def doHello():
print("hello world!") if __name__=='__main__':
doHello()
  • 再试试python test.py,这次只有一次输出了:
will$ python test.py
hello world!
  • 我们再试试python hello.py,也能按照预期输出:
will$ python hello.py
hello world!

  • 对于Java程序员来说,包很好理解,在python中也很相似,接下来咱们尝试一下,创建名为test的包,里面有两个模块:test1和test2

  • 加入包名为test,咱们创建名为test的文件夹

  • test文件夹下,新增文件init.py,这是个空文件

  • 创建文件test1.py:

def doTest1():
print("hello test1!")
  • 再创建文件tes2.py:
def doTest2():
print("hello test2!")
  • 现在回到test2.py文件的上一层目录,创建文件hello.py,用来验证如何使用包,可见访问方式是包名.模块名.方法名:
import test.test1 as test1
import test.test2 as test2 test1.doTest1()
test2.doTest2()
  • 运行hello.py试试:
will$ python hello.py
hello test1!
hello test2!

内建模块:collections

  • Java程序员对collections包不会陌生,这里面都是一些和容器相关的类,为咱们的开发提供了极大便利,接下来看看该模块常用的几个类

  • namedtuple:可以用名字访问内容的元组子类,从下面的代码可见,namedtuple可以方便的定义一个对象,很像java中的bean:

from collections import namedtuple

# 自定义元组对象
Student = namedtuple('Student', ['name', 'age']) # 实例化Student
student = Student('Tom', 11) # 看一下student的类型
print(type(student)) # 使用name字段
print(student.name) # 使用age字段
print(student.age)
  • 执行结果如下,可见student的name和age字段都能方便的访问到,而student实例的类型是class:
will$ python test.py
<class '__main__.Student'>
Tom
11

内建模块:deque

  • deque是双向队列,在增加和删除数据的时候比列表的性能更好(列表的读性能更好),基本操作如下所示:
from collections import deque

# 实例化deque
dq = deque([1,2,3]) # 队列右侧增加元素
dq.append(4) print('1. {}'.format(dq)) # 队列左侧增加元素
dq.appendleft(5) print('2. {}'.format(dq)) # 指定位置增加元素
dq.insert(1, 6) print('3. {}'.format(dq)) # 最右侧元素弹出(删除)
dq.pop() print('4. {}'.format(dq)) # 最左侧元素弹出
dq.popleft() print('5. {}'.format(dq)) # 删除元素,注意2是值,不是位置
dq.remove(2) print('6. {}'.format(dq)) # 倒排
dq.reverse() print('7. {}'.format(dq))
  • 执行结果如下:
will$ python deque.py
1. deque([1, 2, 3, 4])
2. deque([5, 1, 2, 3, 4])
3. deque([5, 6, 1, 2, 3, 4])
4. deque([5, 6, 1, 2, 3])
5. deque([6, 1, 2, 3])
6. deque([6, 1, 3])
7. deque([3, 1, 6])

内建模块:OrderedDict

  • OrderedDict是有顺序的字典,如果您了解LFU(Least frequently used)算法,那么就很容易理解有序的字典了,OrderedDict中的顺序是元素被添加的先后顺序,普通用法如下:
from collections import OrderedDict

# 实例化
od = OrderedDict() # 添加
od['a'] = 1
od['c'] = 2
od['b'] = 3 # 顺序是添加的先后顺序
print("1. {}".format(od)) # 打印所有的键
print(od.keys()) # 把一个字典合并进来
od.update({'e':'4'}) # 顺序是添加的先后顺序
print("2. {}".format(od)) # 根据键删除键值对
od.pop('a') print("3. {}".format(od)) # 把指定键的键值对移到末尾
od.move_to_end('c') print("4. {}".format(od))
  • 输出如下:
will$ python ordered.py
1. OrderedDict([('a', 1), ('c', 2), ('b', 3)])
odict_keys(['a', 'c', 'b'])
2. OrderedDict([('a', 1), ('c', 2), ('b', 3), ('e', '4')])
3. OrderedDict([('c', 2), ('b', 3), ('e', '4')])
4. OrderedDict([('b', 3), ('e', '4'), ('c', 2)])

内建模块:defaultdict

  • defaultdict容易理解:带有默认值的字典,用法如下所示,要注意的是defaultdict实例化的入参是lambda表达式,至于这个lambda,相信java程序员并不陌生:
from collections import defaultdict

dd = defaultdict(lambda: 'ABC')

dd['a'] = 1

# 打印一个存在的键值
print(dd['a']) # 打印一个不存在的键值
print(dd['b'])
  • 输出如下:
will$ python defaultdict.py
1
ABC

内建模块:Counter

  • Counter提供了计数器功能,下面的demo演示了用Counter将列表转为了每个元素的统计结果,要注意的是most_common方法,相当于排序和列表的功能,该方法的返回值是列表,里面的元素是元组:
from collections import Counter

# 一个普通列表
colors = ['aa', 'bb', 'cc', 'aa'] # 将列表传给Counter进行统计
result = Counter(colors) # 打印result类型
print(type(result)) # 打印result内容
print(result) # 用内置函数dict将Counter实例转为字典
print(dict(result)) # 取统计值最高的前两个元素
most = result.most_common(2) # 检查most_common返回值的类型
print("most_common's type {}".format(type(most))) # 检查most_common返回值的类型
print("most_common's value : {}".format(most))
  • 输出结果如下:
will$ python Counter.py
<class 'collections.Counter'>
Counter({'aa': 2, 'bb': 1, 'cc': 1})
{'aa': 2, 'bb': 1, 'cc': 1}
most_common's type <class 'list'>
most_common's value : [('aa', 2), ('bb', 1)]

内建模块:datetime

  • 名为datetime的模块中,有个名为datetime的类

  • 还可以实例化datetime对象:

  • datetime对象的年月日时分秒等字段:

  • 转时间戳:

  • 还可以通过strptime方法将指定格式的字符串转为datetime对象:

  • datetime对象转字符串也是常见操作,用的是strftime方法:

  • 时间的计算,例如一天前,一小时后等操作,可以使用datetime包的timedelta类完成:

  • datetime对象可以用减法结算时间差:

  • 减法特性在计算日期间隔的时候很有用:

JSON处理

  • 利用json进行对象和字符串之间的序列化、反序列化转换:

  • 还可以用dump和load方法通过文件进行序列化反序列化操作

内置模块:random

  • 生成随机数也是常见操作:

  • 还可以产生整形随机数,设置内容范围和递增单位:

  • 在一堆内容中做随机选择:

  • 用choices方法(注意不是choice),可以随机选择指定数量的结果:

  • choices得到的结果可能重复,如果想不重复可以用sample方法:

  • 将原有集合数据的顺序打乱,相当于洗牌的效果:

函数

  • 基本函数语法:
def 函数名([参数列表]):
函数体
  • 和Java不同的是,函数的入参类型并不固定:

  • 使用关键字pass,可以定义一个空方法:
def test():
pass
  • 一个函数可以返回多个值(本质上是个元组),调用的时候用多个变量来接收即可:

  • 还可以给函数增加说明文档,然后用help命令查看:

  • 调用参数的时候可以用参数名=xxx的形式传入参数,此时参数参数的先后顺序可以随意,无所有谁先谁后:

  • 可变参数和Java的方法也相似,先看一个星号的可变参数,可以理解为元组:

  • 再看两个星号的可变参数,可以理解为字典:

  • 对于固定参数的函数,还可以直接将字典作为入参,不过要加两个星号:

  • 还可以设置默认参数:

lambda表达式

  • java程序员对lambda表达式很熟悉,这里也差不多,来看看如何定义和使用:

  • 再来看看几个支持lambda的内置函数,熟悉lambda的使用

  • filter:过滤器,下面是个过滤奇偶数的例子,第一个参数是判断是否过滤的逻辑,True保留,第二个参数是列表,最终奇数全部被剔除,只留下偶数:

  • map:逐一转换,下面是将奇数转为False,偶数转为True的例子:

  • reduce:大名鼎鼎的map reduce,您应该有所耳闻,reduce会将集合中的数据逐个取出来和前面一轮的结果做同样的处理,最典型的当属累加:

  • sort:排序,先来看看最简单的:

  • sorted可以接受排序处理函数作为参数,例如按照绝对值进行排序,内置函数是abs,被作为参数传给sorted:

  • sorted方法会生成一个新的列表,如果想直接改变原列表就不适合用sorted方法了,此时用列表的sort方法即可,如下图,还用了reverse参数试试倒排序的功能:

面向对象

  • 身为Java程序员,天天和对象打交道,下面的代码您应该很容易看懂:

  • 如果变量名是由两个下划线开始的,就表示改变量是私有成员变量,不能在外部访问:

  • 与Java不同的是,创建对象不需要关键字new

  • 继承:

class 派生类名 (父类名):
语句...
  • 下面是个继承的例子,Student是父类,Pupil是子类:
# 父类
class Student:
# 成员变量
name = '未知'
age = 11
__addr= 'ShangHai' # 构造方法
def __init__(self, name, age, addr):
print('执行构造方法')
self.name = name
self.age = age
self.__addr = addr def myInfo(self):
print('学生姓名[{}],年龄[{},地址[{}]]'.format(self.name, self.age, self.__addr)) class Pupil(Student):
#成员变量
grade = 1 # 构造方法
def __init__(self, name, age, addr, grade):
# 显式调用父类构造方法
Student.__init__(self, name, age, grade) print('执行构造方法(子类)')
self.grade = grade # 子类自己的方法
def myGrade(self):
print('学生年级[{}]'.format(self.grade))
  • 执行效果如下,符合预期:

生成器

  • 先回顾一下列表推导,下面的代码会生成一个列表:
a = [x*2 for x in range(10)]
  • 如果列表很大就会很占用内存空间,此时我们还有另一个选择:生成器,简单的说就是将上述代码的方括号改成圆括号,这样a就不是列表了,而是生成器,这是种特殊的迭代器:

异常处理

  • 习惯了java的try-catch-finally,对python的异常处理就容易理解了,捕获和处理如下:
try:
x = 1/0
print('不可能打印这一句')
except ZeroDivisionError as err:
print('发生异常', err)
finally:
print('执行finally')
  • 输出如下图:

  • 关键字raise可以主动抛出异常:

  • 以上就是欣宸在自学Python过程中的简化版笔记,希望能帮助您在初期抓住重点,快速入门;

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢迎关注公众号:程序员欣宸

微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...

https://github.com/zq2599/blog_demos

来自Java程序员的Python新手入门小结的更多相关文章

  1. 为 Java 程序员准备的 Go 入门 PPT

    为 Java 程序员准备的 Go 入门 PPT 这是 Google 的 Go 团队技术主管经理 Sameer Ajmani 分享的 PPT,为 Java 程序员快速入门 Go 而准备的. 视频 这个 ...

  2. 【Python】Java程序员学习Python(五)— 函数的定义和使用

    不想做一个待宰的羔羊!!!!要自己变得强大.... 函数的定义和使用放在最前边还是有原因的,现在语言趋于通用,基本类型基本都是那些,重点还是学习对象的使用方法,而最根本的还是方法的使用,因此优先介绍, ...

  3. 【Python】Java程序员学习Python(二)— 开发环境搭建

    巧妇难为无米之炊,我最爱的还是鸡蛋羹,因为我和鸡蛋羹有段不能说的秘密. 不管学啥,都要有环境,对于程序员来说搭建个开发环境应该不是什么难题.按顺序一步步来就可以,我也只是记录我的安装过程,你也可以滴. ...

  4. 【Python】Java程序员学习Python(六)— 流程控制、异常处理

    和Java语言一样,Python也有基本的流程控制,简单了解下即可. 一.流程控制的元素 条件 条件就是布尔值或者布尔值的表达式,要么是True要么是False. 代码块 在Python中,代码块不是 ...

  5. Java程序员之Spring(一) 入门

    一. Spring 原理讲解  Spring 是一个轻量容器框架(开源):Spring的核心是 IoC(控制反转) 和 AOP(面向切面编程): Spring 由7个模块组成: Spring Core ...

  6. 【Python】Java程序员学习Python(三)— 基础入门

    一闪一闪亮晶晶,满天都是小星星,挂在天上放光明,好像许多小眼睛.不要问我为什么喜欢这首歌,我不会告诉你是因为有人用口琴吹给我听. 一.Python学习文档与资料 一般来说文档的资料总是最权威,最全面的 ...

  7. 【Python】Java程序员学习Python(七)— 文本类详解(字符串、str)

    如果一个女孩子喜欢看龙猫,那么请珍惜她,呵护她 任何一门语言,字符串总是最基本也是最需要掌握的一个变量,想想入门的Hello World,输出的就是字符串. 官方文档:https://docs.pyt ...

  8. 【Python】Java程序员学习Python(十)— 类、包和模块

    我觉得学习到现在应该得掌握Python的OOP编程了,但是现在还没有应用到,先留一个坑. 一.类和对象 说到类和对象其实就是在说面向对象编程,学完Java以后我觉得面向对象编程还是很不错的,首先封装了 ...

  9. 【Python】Java程序员学习Python(四)— 内置方法和内置变量

    <假如爱有天意> 当天边那颗星出现,你可知我又开始想念,有多少爱恋只能遥遥相望,就像月光洒向海面,年少的我们曾以为,相爱的人就能到永远,当我们相信情到深处在一起,听不见风中的叹息,谁知道爱 ...

随机推荐

  1. 搭建简单的SpringCloud项目三:问题及解决

    GitHub:https://github.com/ownzyuan/test-cloud 前篇:搭建简单的SpringCloud项目一:注册中心和公共层 搭建简单的SpringCloud项目二:服务 ...

  2. 巩固javawbe第二天

    巩固内容: <!DOCTYPE> 声明 <!DOCTYPE>声明有助于浏览器中正确显示网页. 网络上有很多不同的文件,如果能够正确声明HTML的版本,浏览器就能正确显示网页内容 ...

  3. 【leetcode】834. Sum of Distances in Tree(图算法)

    There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges. You are ...

  4. 连接查询条件在on后面和条件在where后面

    emp表结构如下: dept表结构如下: 内连接 条件语句放在on 后面和 where 结果对于inner join结果是一样的 但对于left join 结果会产生不一样 这种现象也比较好理解,如果 ...

  5. How exactly does Google AdWords work?

    The key to how Google AdWords works is the Quality Score. Quality Score is generally how well an ad ...

  6. When should we write our own assignment operator in C++?

    The answer is same as Copy Constructor. If a class doesn't contain pointers, then there is no need t ...

  7. dom4j解析XML学习

    原理:把dom与SAX进行了封装 优点:JDOM的一个智能分支.扩充了其灵活性增加了一些额外的功能. package com.dom4j.xml; import java.io.FileNotFoun ...

  8. redis入门到精通系列(八):redis的高可用--主从复制详解

    (一)主从复制介绍 前面所讲的关于redis的操作都属于单机操作,单机操作虽然操作简单,但是处理能力有限,无法高可用.所谓高可用性,就是指当一台服务器宕机的时候,有备用的服务器能顶替上,在单机操作上这 ...

  9. contrller层的编码设设计流程以及详细配置

    /**      实际开发中遵循一个规律:自己写的类使用注解,系统提供的类使用配置文件 1.书写controller类----->配置springmvc.xml-------->配置web ...

  10. 使用ajax对用户注册时,用户名进行检验

    package cn.hopetesting.com.servlet;import com.fasterxml.jackson.databind.ObjectMapper;import javax.p ...