5高阶内容(上)

185 阅读10分钟

字符串的高阶用法

%百分号模式

name = "Python"
print("我的名字是" + name + "!")
print("我的名字是%s!" % name)

输出:

我的名字是Python!
我的名字是Python!

同样是输出一个可配置的字符串,有两种不同的方式。而上面第二种,相对而言就算比较简单的,因为当字符串里面要传入的参数变多的时候, 第一种方式将会很混乱。

name = "Python"
age = 18
gender = "男"
print("我的名字是" + name + "!我" + str(age) + "岁了,我是" + gender + "的~")
print("我的名字是 %s !我 %d 岁了,我是 %s 的~" % (name, age, gender))

输出:

我的名字是Python!我18岁了,我是男的~
我的名字是 Python !我 18 岁了,我是 男 的~

如果输入的参数数量很多的话,可以借用字典的形式来填入数据:

name = "Python"
age = 18
gender = "男"
print("我的名字是 %(nm)s !我 %(age)d 岁了,我是 %(gd)s 的~" % {"nm": name, "age":age, "gd":gender})

输出:

我的名字是 Python !我 18 岁了,我是 男 的~

因为用字典就不用关心后面参数的顺序,而且有的时候,还可以重复利用字典里面的 key 做索引。

方式意思
%d整数
%i整数
%f小数
%s字符
name = "Python"
age = 18
height = 1.8
print("我的名字是 %s !我 %d 岁了,我 %f 米高~" % (name, age, height))

输出:

我的名字是 Python !我 18 岁了,我 1.800000 米高~

关于字符和数字类型,如果你在数字类型(%d,%f)里输入的是字符,它就报错了,但是你在字符类型(%s)里输入的是数字,就会将数字识别为字符,不会报错


还有一个比较常用的方式,就是当使用小数的时候, %f 可以打印出很长一串数字。有时候不需要太长的位数,可以让它短一点,输出固定长度的小数。

print("%f" % (1/3))
print("%.2f" % (1/3))

输出:

0.333333
0.33
print("%f" % (1/3))     # 后面不限制
print("%.2f" % (1/3))   # 后面限制 2 个位置
print("%4d" % (1/3))    # 前面补全最大 4 个位置
print("%5d" % 12)       # 前面补全最大 5 个位置

输出:

0.333333
0.33
   0
   12

format

fotmat作为Python的的格式字符串函数,主要通过字符串中的花括号{},来识别替换字段,从而完成字符串的格式化。它通过{}:来代替%

%进行对比:

name = "Python"
age = 18
height = 1.8
print("我的名字是 %s !我 %d 岁了,我 %f 米高~" % (name, age, height))
print("我的名字是 {} !我 {} 岁了,我 {} 米高~".format(name, age, height))

输出:

我的名字是 Python !我 18 岁了,我 1.800000 米高~
我的名字是 Python !我 18 岁了,我 1.8 米高~

字符串的format函数可以接受不限个参数,位置可以不按顺序,可以不用或者用多次(Python 2.7以后才能为能为空{}

name = "Python"
age = 18
height = 1.8
print("我的名字是 {0} !我 {1} 岁了,我 {2} 米高~我是{0}".format(name, age, height))

输出:

我的名字是 Python !我 18 岁了,我 1.8 米高~我是Python

除了按照 index 来传字符,也可以用字典模式。只要在 {} 传入一个 key 的名字就好。这样子也是可以复用参数的,方便很多。

name = "Python"
age = 18
height = 1.8
print("我的名字是 {nm} !我 {age} 岁了,我 {ht} 米高~我是{nm}".format(nm=name, age=age, ht=height))

输出:

我的名字是 Python !我 18 岁了,我 1.8 米高~我是Python

在显示小数或数字时,可以有更丰富的控制。

print("我 {:.3f} 米高".format(1.12345))
print("我 {ht:.1f} 米高".format(ht=1.12345))
print("我 {:3d} 米高".format(1))
print("我 {:3d} 米高".format(21))

输出:

我 1.123 米高
我 1.1 米高
我   1 米高
我  21 米高
方式意思
:,每 3 个 0 就用逗号隔开,比如 1,000
:b该数字的二进制
:d整数型
:f小数模式
:%百分比模式

例如:

txt = "You scored {:%}"
print(txt.format(2.1234))

txt = "You scored {:.2%}"
print(txt.format(2.1234))

输出:

You scored 212.340000%
You scored 212.34%

f格式化字符串

这个是 Python 3.6 之后引入的一个功能

name = "Python"
age = 18
height = 1.8
print(f"我的名字是 {name} !我 {age} 岁了,我 {height} 米高~")

输出:

我的名字是 Python !我 18 岁了,我 1.8 米高~

注意,在使用 f 模式的情况下,要在字符串开头加上一个 f。然后用 {} 圈出你的变量名,直接在 {} 引用变量。

甚至还可以在 {} 里做运算,比如下面这样:

print(f"我 {age} 岁了,明年我就{age + 1}岁了~")

输出:

我 18 岁了,明年我就19岁了~

它同样还是保留了一些特殊写法,包括限制字符长度等。做法都和 % 还有 format 类似。

score = 2.1234
print(f"You scored {score:.2%}")
print(f"You scored {score:.3f}")
print(f"You scored {12:5d}")

输出:

You scored 212.34%
You scored 2.123
You scored    12

修改字符串

除了多样化拼接字符串,比如用 %format 或者 f 方式,还可以用一些字符串功能来处理文字的更多需求。

方式意思
strip去除两端的空白符
replace替换字符
lower全部做小写处理
upper全部做大写处理
title仅开头的字母大写
split按要求分割
join按要求合并
startswith判断是否为某字段开头
endswith判断是否为某字段结尾

例如:

"  我不想要前后的空白,但是  中间\n的可以有\n  ".strip()

输出:

我不想要前后的空白,但是  中间
的可以有
"替换掉小明".replace("小明", "志强")

输出:

替换掉志强
# 文字大小写处理
print("How ABOUT lower CaSe?".lower())
print("And upper CaSe?".upper())
print("do tiTle For me".title())

输出:

how about lower case?
AND UPPER CASE?
Do Title For Me
print("你|帮|我|拆分|一下|这句话".split("|"))
print("|".join(["你","帮", "我", "重组", "一下", "这句话"]))

输出:

['你', '帮', '我', '拆分', '一下', '这句话']
你|帮|我|重组|一下|这句话
print("我在街头看到你".startswith("我在"))
print("我在街头看到你".startswith("街头"))
print("我在巷尾看到你".endswith("看到你"))
print("我在巷尾看到你".endswith("巷尾"))

输出:

True
False
True
False

Python的偷懒用法

Lambda: 更直接的 Function

在 Python 中,我们肯定会定义功能 Function,或者 method,无论你管它叫什么,它都是一个会执行你任务的功能。

def add(a, b):
    return a + b

print(add(1,2))

输出:

3

即使是一个简单的 add 功能,都要写一长串的固定格式才能把它当功能使用。

如果情况是:

  1. 功能很简单
  2. 调用次数不多(没那么正式的功能)

就可以用 lambda 来写功能。

add = lambda a, b: a+b
print(add(1,2))

输出:

3

lambda 在Python编程中使用的频率非常高,我们通常提及的lambda表达式其实是python中的一类特殊的定义函数的形式,使用它可以定义一个匿名函数。即当你需要一个函数,但又不想费神去命名一个函数,这时候,就可以使用 lambda了。

lambda函数的语法只包含一个语句:lambda [arg1 [,arg2,.....argn]]:expression。其中,lambda是Python预留的关键字,argexpression由用户自定义。

for循环的简洁用法

你是否有这么一个时候:

  1. 我想要出一个列表,
  2. 然后用 for 循环不断添加列表里的元素。

一般写法:

l = []
for i in range(10):
    l.append(i*2)
print(l)

输出:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

简洁写法:

l = [i*2 for i in range(10)]	# 将for循环写进列表内部
print(l)

也可以用在字典上:

d = {"index"+str(i): i*2 for i in range(10)}
print(d)

输出:

{'index0': 0, 'index1': 2, 'index2': 4, 'index3': 6, 'index4': 8, 'index5': 10, 'index6': 12, 'index7': 14, 'index8': 16, 'index9': 18}

这种列表/字典的生成方式只适合 for 内部只有比较简单的运算逻辑的情况。

判断逻辑的简洁用法

那些简单的 if-else 判断,如果写成多行,有时候工作量会比较大。比如:

done = False
if done:
    a = 1
else:
    a = 2
print(a)

输出:

2

可以简化为:

done = False
a = 1 if done else 2
print(a)

如果你的 if else 逻辑很复杂,比如里面还有 elif 这种逻辑,就不要用一行写。

一行只是为了减少你处理简单情况的时间。如果你在一行里面写了太多逻辑,阅读起来就很困难了。

for+判断的简洁写法

在这种情况下,通常是处理一种特殊的列表/字典生成方式。

  1. 要用一行 for 生成一个列表/字典
  2. 对原始数据进行判断,符合要求的生成,不符合的抛弃
l = []
for i in range(10):
    if i % 2 == 0:		# 0,2,4,6,8
        l.append(i*2)
print(l)

输出:

[0, 4, 8, 12, 16]

forif else的简写模式合并。

l = [i*2 for i in range(10) if i%2==0]
print(l)

字典类似:

d = {"index"+str(i): i*2 for i in range(10) if i % 2 == 0}
print(d)

输出:

{'index0': 0, 'index2': 4, 'index4': 8, 'index6': 12, 'index8': 16}

enumerate

想在 for 里面记个数,并且到某个数的时候做特殊处理的时候,例如:

count = 0
l = [11,22,33,44]
for data in l:
    if count == 2:
        data += 11
    l[count] = data
    count += 1
print(l)

输出:

[11, 22, 44, 44]

这时候利用enumerate() 函数:

l = [11,22,33,44]
for count, data in enumerate(l):
    if count == 2:
        data += 11
    l[count] = data
print(l)

输出:

[11, 22, 44, 44]

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。(python2.3以上可以用)

这个函数的基本应用就是用来遍历一个集合对象,它在遍历的同时还可以得到当前元素的索引位置。

enumerate() 方法的语法:enumerate(sequence, [start=0])

  • sequence -- 一个序列、迭代器或其他支持迭代对象。
  • start -- 下标起始位置。

enumerate() 方法返回 enumerate(枚举) 对象。

names = ["Alice","Bob","Carl"]
for index,value in enumerate(names):
    print(f'{index}: {value}')

输出:

0: Alice
1: Bob
2: Carl

这个循环遍历了names列表的所有元素,并通过增加从零开始的计数器变量来为每个元素生成索引。

也可以初始化 count 到不同的数值:

l = [11,22,33,44]
d = {}
for count, data in enumerate(l, start=5):
    d[count] = data
print(d)

输出:

{5: 11, 6: 22, 7: 33, 8: 44}

Zip

同时处理两个列表,一个是姓名一个是分数,并把它们做成一个字典:

name = ["a", "b", "c"]
score = [1,2,3]
d = {}
for i in range(3):
    d[name[i]] = score[i]
print(d)

输出:

{'a': 1, 'b': 2, 'c': 3}

此时可以利用zip() 进行简化。

name = ["a", "b", "c"]
score = [1,2,3]
d = {}
for n, s in zip(name, score):
    d[n]=s
print(d)

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

zip 语法:zip([iterable, ...])iterabl -- 一个或多个迭代器;

返回元组列表。

name = ["a", "b", "c"]
score = [1,2,3]
bonus = [1,0,1]
d = {}
for n, s, b in zip(name, score, bonus):
    d[n]=s+b
print(d)

输出:

{'a': 2, 'b': 2, 'c': 4}

reverse & reversed

翻转列表:

l = [1,2,3]
_l = []
for i in range(len(l)):
    _l.append(l[-i-1])
print(_l)

输出:

[3, 2, 1]

Python本身自带翻转功能。

1.就地翻转

l = [1,2,3]
l.reverse()
print(l)

2.在for循环中运用翻转迭代器

l = [1,2,3]
for i in reversed(l):
    print(i)

输出为:
3
2
1

3.拷贝出副本翻转

l = [1,2,3]
_l = l[::-1]

print(_l)