python高级特性:切片/迭代/列表生成式/生成器

简介: 廖雪峰老师的教程上学来的,地址:python高级特性  下面以几个具体示例演示用法: 一、切片 1.1 利用切片实现trim def trim(s): while s[:1] == " " or s[-1:] == " ": # 若第1个元素或最后1个元素为空格 ...

廖雪峰老师的教程上学来的,地址:python高级特性 

下面以几个具体示例演示用法:

一、切片

1.1 利用切片实现trim

def trim(s):
    while s[:1] == " " or s[-1:] == " ": # 若第1个元素或最后1个元素为空格
        if s[:1] == " ":
            s = s[1:]
        if s[-1:] == " ":
            s = s[:-1]
    return s

注:字符串可以看做一个list,列表切片的完整写法是 L[start:end],其中end也支持负数,最后一个数用-1表示,第1个数用0表示,如果省略start,表示从0开始,如果省略end,表示到最后1个元素结束。

测试代码:

if trim('hello  ') != 'hello':
    print('测试失败1!')
elif trim('  hello') != 'hello':
    print('测试失败2!')
elif trim('  hello  ') != 'hello':
    print('测试失败3!')
elif trim('  hello  world  ') != 'hello  world':
    print('测试失败4!')
elif trim('') != '':
    print('测试失败5!')
elif trim('    ') != '':
    print('测试失败6!')
else:
    print('测试成功!')

1.2 切片还有第3个参数,即:L[start:end:skip],比如在1-10之间,把奇数、偶数选出来

list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

odd = list_1[::2]
even = list_1[1::2]

print(odd)
print(even)

输出:

[1, 3, 5, 7, 9]
[2, 4, 6, 8, 10]

 

二、迭代

list_1 = list(range(1, 11))

print("正向迭代:")
for x in list_1:
    print(x)

print("\n反向迭代:")
for x in reversed(list_1):
    print(x)

print('\n带索引的迭代:')
for m in enumerate(list_1):
    print("list_1[", m[0], "]=", m[1])

dic_1 = {"name": "菩提树下的杨过", "blog": "http://yjmyzz.cnblogs.com/"}

# 字典的迭代
print("\ndict字典迭代1:")
for k in dic_1:
    print("key:", k, ",value:", dic_1[k])

print("\ndict字典迭代2:")
for v in dic_1.values():
    print("value:", v)

print('\ndict字典迭代3:')
for k, v in dic_1.items():
    print("key:", k, ",value:", v)

输出:

正向迭代:
1
2
3
4
5
6
7
8
9
10

反向迭代:
10
9
8
7
6
5
4
3
2
1

带索引的迭代:
list_1[ 0 ]= 1
list_1[ 1 ]= 2
list_1[ 2 ]= 3
list_1[ 3 ]= 4
list_1[ 4 ]= 5
list_1[ 5 ]= 6
list_1[ 6 ]= 7
list_1[ 7 ]= 8
list_1[ 8 ]= 9
list_1[ 9 ]= 10

dict字典迭代1:
key: name ,value: 菩提树下的杨过
key: blog ,value: http://yjmyzz.cnblogs.com/

dict字典迭代2:
value: 菩提树下的杨过
value: http://yjmyzz.cnblogs.com/

dict字典迭代3:
key: name ,value: 菩提树下的杨过
key: blog ,value: http://yjmyzz.cnblogs.com/

  

三、列表生成器

这个老厉害了!比如:要找出1~100内所有奇数的平方数(即:1,3,5... 这些数的平方数)

a = [x ** 2 for x in range(1, 101) if x % 2 == 1 and x ** 2 <= 100]
print(a)

输出:[1, 9, 25, 49, 81]

再比如,打印出当前目录下的所有文件(不考虑递归子目录) 

import os

print([f for f in os.listdir(".")])

小结:写法就是 [... for ... in .. if ...] ,要生成的list项写在for前面,如果迭代时需要指定条件,写在最后的if中。

 

四、生成器(generator)

这是python引入的一个新概念,想想刚才学到的列表生成器:

result1 = [x ** 2 for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
print(type(result1), result1)

输出:

<class 'list'> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

不知道大家想过没有:如果for前面的运算比较复杂(比如:求平方根),而for迭代的列表又很大(比如:1千万个),最终列表生成器肯定运行很慢,会严重影响性能。能不能做到『延时』计算?等到真正要用的时候,再按需计算。这就是生成器(generator)要解决的问题,它与[列表生成器]的区别在于,它只保存计算逻辑(即: 保存算法),并不马上计算结果,真正要用的时候,调用next(g)取出下一个计算结果即可,当然,它也支持迭代。

generator1 = (x ** 2 for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(type(generator1), generator1)

# 取出第1个值
print(next(generator1))
# 取出第2个值
print(next(generator1))

# 打印剩余的值
for x in generator1:
    print(x)

输出:

<class 'generator'> <generator object <genexpr> at 0x1087e7f10>
1
4
9
16
25
36
49
64
81
100

从输出类型上看,它的类型是generator,而非list。单纯从语法上看,只要把"列表生成器"的[],换成()即可。

再来一个复杂点的示例,中学我们都学过"杨辉三角",如果用常规思路,打印出杨辉三角,可以参考下面的代码:

import copy

def triangles(limit):
    first, second = [1], [1, 1]
    print(first)
    if limit > 1:
        print(second)
        if limit == 2:
            return
        x = copy.copy(second)
        while True:
            y = copy.copy(first)
            [y.append(x[i] + x[i + 1]) for i in range(len(x) - 1)]
            y.append(1)
            print(y)
            x = copy.copy(y)
            if len(y) >= limit:
                return


triangles(10)

输出:

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

如果,要改写成生成器(generator),该怎么做呢?答案:只要把print(...)的地方,改成yield 即可。

def triangles_generator(limit):
    first, second = [1], [1, 1]
    yield first
    if limit > 1:
        yield second
        if limit == 2:
            return
        x = copy.copy(second)
        while True:
            y = copy.copy(first)
            [y.append(x[i] + x[i + 1]) for i in range(len(x) - 1)]
            y.append(1)
            yield y
            x = copy.copy(y)
            if len(y) >= limit:
                return


g = triangles_generator(10)
# 取出前2个
print(next(g))
print(next(g))
# 剩下的用迭代写法输出
for x in g:
    print(x)

输出与刚才相同,就不重复贴了。关于这个yield,如果还没理解的,可以对比看下面的示例:

def test1():
    return [1, 2, 3]


def test2():
    print("test2=>1")
    yield 1
    print("test2=>2")
    yield 2
    print("test2=>3")
    yield 3


print(test1())
g = test2()
print(next(g))
print(next(g))
print(next(g))

输出:

[1, 2, 3]
test2=>1
1
test2=>2
2
test2=>3
3

test2()遇到yield后,会停下来,保存现场,等待下一次调用next()时,才会继续执行。

作者: 菩提树下的杨过
出处: http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
目录
相关文章
|
2月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
199 1
|
2月前
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
181 0
|
5月前
|
人工智能 数据安全/隐私保护 Python
小红书图文生成器,小红书AI图文生成工具,python版本软件
Pillow库自动生成符合平台尺寸要求的配图7;3)利用Playwright实现自动化发布流程6。
|
5月前
|
数据采集 NoSQL 调度
当生成器遇上异步IO:Python并发编程的十大实战兵法
本文通过十大实战场景,详解Python中生成器与异步IO的高效结合。从协程演进、背压控制到分布式锁、性能剖析,全面展示如何利用asyncio与生成器构建高并发应用,助你掌握非阻塞编程核心技巧,提升I/O密集型程序性能。
173 0
|
2月前
|
索引 Python
Python 列表切片赋值教程:掌握 “移花接木” 式列表修改技巧
本文通过生动的“嫁接”比喻,讲解Python列表切片赋值操作。切片可修改原列表内容,实现头部、尾部或中间元素替换,支持不等长赋值,灵活实现列表结构更新。
130 1
|
2月前
|
索引 Python
098-python列表_切片_slice_开始_结束
本文介绍了Python中列表的切片(slice)操作,通过“前闭后开”原则截取列表片段,支持正负索引、省略端点等用法,并结合生活实例(如切面包、直播切片)帮助理解。切片不改变原列表,返回新列表。
247 4
|
8月前
|
开发者 Python
Python代码设计:使用生成器替代回调函数
本文探讨了在处理大文件时计算MD5值的实现方法,并展示了如何通过回调函数、生成器和类等方式输出进度。首先介绍了通过回调函数更新进度的方式,然后优化为使用生成器简化调用者代码,最后对比了两种方式的优缺点。虽然生成器使代码更简洁,但在异常处理上不如回调函数灵活。作者通过实例分析,帮助开发者根据需求选择合适的方式。
163 16
|
3月前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
254 2
|
4月前
|
传感器 数据采集 监控
Python生成器与迭代器:从内存优化到协程调度的深度实践
简介:本文深入解析Python迭代器与生成器的原理及应用,涵盖内存优化技巧、底层协议实现、生成器通信机制及异步编程场景。通过实例讲解如何高效处理大文件、构建数据流水线,并对比不同迭代方式的性能特点,助你编写低内存、高效率的Python代码。
225 0
|
3月前
|
大数据 数据处理 数据安全/隐私保护
Python3 迭代器与生成器详解:从入门到实践
简介:本文深入解析Python中处理数据序列的利器——迭代器与生成器。通过通俗语言与实战案例,讲解其核心原理、自定义实现及大数据处理中的高效应用。
168 0

推荐镜像

更多