侧边栏壁纸
博主头像
秋之牧云博主等级

怀璧慎显,博识谨言。

  • 累计撰写 68 篇文章
  • 累计创建 41 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Python高级特性

秋之牧云
2024-06-15 / 0 评论 / 0 点赞 / 84 阅读 / 9339 字

切片(Slice)

  • 切片:截取listtuple或者str的元素

L = [0, 1, 2, 3, 4, 5]

print(L[: 3])  # [0, 1, 2]
print(L[0:3])  # [0, 1, 2]
print(L[0:])  # [0, 1, 2, 3, 4, 5]
print(L[:])  # [0, 1, 2, 3, 4, 5]
print(L[2:4])  # [2, 3]

print(L[::2])  # [0, 2, 4] 指定步长

print(L[-3:])  # [3, 4, 5]
print(L[:-1])  # [0, 1, 2, 3, 4]
print(L[-4:-1])  # [2, 3, 4]
  • 实现一个trim()函数,去除字符串首尾的空格(不使用strstrip()函数)

def my_trim(s):
    while s and s[0] == ' ':  # 去除开头的空格
        s = s[1:]
    while s and s[-1] == ' ':  # 去除结尾的空格
        s = s[:-1]
    return s

迭代(Iteration)

  • 在Python中,迭代是通过for ... in来完成的

L = list(range(10))

for i in L:
    print(i)
L = list(range(10))

# 把一个list变成索引-元素对
for i, x in enumerate(L):
    print(i, x)
# for-in循环可以同时引用多个变量
for x, y, z in [(1, 1, 1), (2, 4, 8), (3, 9, 27)]:
    print(x, y, z)

  • 判断对象是否可迭代(Iterable)

from collections.abc import Iterable

print(isinstance('str', Iterable))  # True
print(isinstance([1, 2, 3], Iterable))  # True
print(isinstance((1, 2, 3), Iterable))  # True
print(isinstance({'1': 1, '2': 2}, Iterable))  # True
print(isinstance({1, 2, 3}, Iterable))  # True
print(isinstance(1, Iterable))  # False
  • 迭代dict 元素

d = {'A': 1, 'B': 2, 'C': 3}

# 迭代键值对
for k, v in d.items():
    print(k, v)

# 迭代keys
for k in d.keys():
    print(k)

# 迭代values
for v in d.values():
    print(v)
  • 使用迭代查找一个list中最小和最大值,并返回一个tuple

def find_min_and_max(L):
    if len(L) == 0:
        return None, None
    minV = L[0]
    maxV = L[0]
    for i in range(len(L)):
        if L[i] > maxV:
            maxV = L[i]
        if L[i] < minV:
            minV = L[i]
    return minV, maxV


if find_min_and_max([]) != (None, None):
    print('测试失败!')
elif find_min_and_max([7]) != (7, 7):
    print('测试失败!')
elif find_min_and_max([7, 1]) != (1, 7):
    print('测试失败!')
elif find_min_and_max([7, 1, 3, 9, 5]) != (1, 9):
    print('测试失败!')
else:
    print('测试成功!')

列表生成式(List Comprehensions)

  • 生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 使用range函数
print(list(range(1, 11)))

# 使用列表生成式
print([x for x in range(1, 11)])
  • for循环后面还可以加上if判断,这样就可以筛选出仅偶数的平方

# [2, 4, 6, 8, 10]
print([x for x in range(1, 11) if x % 2 == 0])
  • 使用两层循环,可以生成全排列

# ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
print([m + n for m in 'ABC' for n in 'XYZ'])
  • 列出当前目录下的所有文件和目录名

# ['.idea', '.venv', 'demo.py']
print([d for d in os.listdir('.')])
  • for循环可以使用多个变量,列表生成式也可以使用多个变量,列表生成式也可以使用两个变量来生成list

d = {'x': 'A', 'y': 'B', 'z': 'C'}

# ['x=A', 'y=B', 'z=C']
print([k + '=' + v for k, v in d.items()])
  • 对于列表生成式,for循环前面的if需要加else,因为要计算出一个确定的值,而for循环后面的if不能加else,因为这是过滤条件

# [6, 4, 10]
# 在一个列表生成式中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else
L = [(x if x % 2 == 0 else x * 2) for x in [1, 2, 3, 4, 5] if x > 2]
  • 过滤出字符串并转换为小写

L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [s.lower() for s in L1 if isinstance(s, str)]

生成器(generator)

  • 创建生成器,只需要把李彪生成式的[]改成() ,列表生成式会直接计算出结果,而生成器保存的是算法,每一个元素可以按照该算法推算出来

g = (x * x for x in range(10))

# <generator object <genexpr> at 0x0000015F56E7E800>
print(g)
  • 如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值,直到抛出StopIteration的错误

g = (x * x for x in range(10))

print(next(g))  # 0
print(next(g))  # 1
print(next(g))  # 2
print(next(g))  # 3
  • 正常使用时基本不会使用next()方法,正确的方法是使用for循环,因为generator也是可迭代对象,并且不需要关心StopIteration的错误

from collections.abc import Iterable

g = (x * x for x in range(10))

print(isinstance(g, Iterable))  # True

# 使用for循环迭代生成器
for i in g:
    print(i)
  • 如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现,比如斐波拉契数列

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        # 相当于
        # t = (b, a + b) # t是一个tuple
        # a = t[0]
        # b = t[1]
        a, b = b, a + b
        n = n + 1
    return 'done'


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

如果想要拿到返回值,必须捕获StopIteration错误。

g = fib(10)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break

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

# <generator object fib at 0x000002253550EEA0>
print(fib(100))
  • 生成器在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行,比如

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield (3)
    print('step 3')
    yield (5)


# 每次调用生成器函数会返回一个全新的生成器
g = odd()
print(next(g))  # 1
print(next(g))  # 2
print(next(g))  # 3
          1
         / \
        1   1
       / \ / \
      1   2   1
     / \ / \ / \
    1   3   3   1
   / \ / \ / \ / \
  1   4   6   4   1
 / \ / \ / \ / \ / \
1   5   10  10  5   1

把每一行看做一个list,试写一个generator,不断输出下一行的list:

迭代器

0

评论区