python learning3

本文介绍了Python中列表切片的使用方法,并详细探讨了生成器的概念及其应用场景,包括通过生成器实现内存友好的数据处理。

In [ ]:
#切片
In [1]:
a=list(range(100))
In [2]:
a[1:19]
Out[2]:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
In [3]:
a[:9]
Out[3]:
[0, 1, 2, 3, 4, 5, 6, 7, 8]
In [5]:
a[-10:-1]
Out[5]:
[90, 91, 92, 93, 94, 95, 96, 97, 98]
In [7]:
a[1:10:2]#2代表间距
Out[7]:
[1, 3, 5, 7, 9]
In [ ]:
#tuple也可以用切片,字符串也看成是一种list
In [8]:
'ASDGHJK'[1:5]
Out[8]:
'SDGH'

最后一个小问题,如果要对list实现类似Java那样的下标循环怎么办? Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

In [9]:
for i, value in enumerate(['A', 'B', 'C']):
    print(i, value)
0 A
1 B
2 C
In [11]:
#那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代
Out[11]:
True

列表生成式

list comprehensions

eg:list(range(10))

In [12]:
L=[]
for x in range(1,11):
    L.append(x*x)
L
Out[12]:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
In [13]:
#写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,
#十分有用,多写几次,很快就可以熟悉这种语法。

#for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方

[x*x for x in range(1,11) if x%2==0]
Out[13]:
[4, 16, 36, 64, 100]
In [14]:
#还可以使用两层循环,可以生成全排列:
[m+n for m in 'ABC' for n in 'XYZ']
Out[14]:
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
In [17]:
#例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:
import os
[d for d in os.listdir('.')]
In [19]:
d={'x':'A','y':'B','z':'C'}
for k,v in d.items():
    print(k,'=',v)
x = A
z = C
y = B
In [21]:
d={'x':'A','y':'B','z':'C'}
[k+'='+v for k,v in d.items()]
Out[21]:
['x=A', 'z=C', 'y=B']
In [22]:
#把所有字符串变小写
L = ['Hello', 'World', 'IBM', 'Apple']
[s.lower() for s in L]
Out[22]:
['hello', 'world', 'ibm', 'apple']

生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

In [25]:
L=[x*x for x in range(10)]
L
Out[25]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [26]:
g=(x*x for x in range(10))
g
Out[26]:
<generator object <genexpr> at 0x00000179FAA522B0>
In [27]:
#使用next得到generator下一个值
next(g)
Out[27]:
0
In [28]:
next(g)
Out[28]:
1
In [29]:
#更常见的是使用循环
for n in g:
    print(n)
4
9
16
25
36
49
64
81
In [30]:
#著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
def fib (max):
    n,a,b =0,0,1
    while n<max:
        print(b)
        a,b=b,a+b
        n=n+1
    return
In [31]:
fib(6)
1
1
2
3
5
8
In [44]:
#上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了:
def fib (max):
    n,a,b =0,0,1
    while n<max:
        yield b
        a,b=b,a+b
        n=n+1
    return 'done'
In [60]:
f=fib(6)
f
Out[60]:
<generator object fib at 0x00000179FAA52570>
In [61]:
i=0
for n in f:
    print(n)
1
1
2
3
5
8
In [50]:
#而变成generator的函数,在每次调用next()的时候执行,
#遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield 3
    print('step 3')
    yield 5
o=odd()
next(o)
step 1
Out[50]:
1
In [51]:
next(o)
step 2
Out[51]:
3
In [64]:
#怎样取得generator中的值呢
#但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,
#必须捕获StopIteration错误,返回值包含在StopIteration的value中:
g = fib(6)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break
            
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
In [ ]:
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值