03-高级特性

#!/usr/bin/env python
# -- coding: utf-8 --

__author__ = 'sunh'

'''
切片操作 Slice
'''
r = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
print r[0:3]  # ['a', 'b', 'c']
# 记住倒数最后一个元素的索引是-1。

# 我们先创建一个0-99的数列
L = range(100)
print L
# 可以通过切片轻松取出某一段数列。比如前10个数:
print L[:10]
# 后10个
print L[-10:]
# 前 10~20个
print L[10:20]
#  前10个数,每两个取一个:
print L[:10:2]
# 所有数,每5个取一个:
print L[::5]

# 甚至什么都不写,只写[:]就可以原样复制一个list:
print L[:]
# tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
print (0, 1, 2, 3, 4, 5)[:3]
# 字符串’xxx’或Unicode字符串u’xxx’也可以看成是一种list,每个元素就是一个字符。
# 因此,字符串也可以用切片操作,只是操作结果仍是字符串:
print 'ABCDEFG' [:3]
print 'ABCDEFG'[::2]

'''
迭代
'''
# 因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
# list这种数据类型虽然有下标,但很多其他数据类型是没有下标的,
# 但是,只要是可迭代对象,无论有无下标,都可以迭代,比如dict就可以迭代:
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
    print key
# 默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.itervalues(),
# 如果要同时迭代key和value,可以用for k, v in d.iteritems()。
for value in d.itervalues():
    print value

for k, v in d.iteritems():
    print k, v

# 如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
from collections import Iterable
print isinstance('abc', Iterable)  # str是否可迭代 True
print isinstance([1, 2, 3], Iterable)  # list是否可迭代 True
print isinstance(123, Iterable)  # 整数是否可迭代 False

# Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

for i, value in enumerate(['A', 'B', 'C']):
    print i, value

# for循环里,同时引用了两个变量,在Python里是很常见的,比如下面的代码:
for x, y in [(1, 1), (2, 4), (3, 9)]:
    print x, y


'''
列表生成式
'''

# 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
# 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用range(1, 11):
print range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 如果要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?
print [x * x for x in range(1, 11)]
# for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
print [x * x for x in range(1, 11) if x % 2 == 0]
# 还可以使用两层循环,可以生成全排列:
print [m + n for m in 'ABC' for n in 'XYZ']
# 运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:
import os  # 导入os模块
print [d for d in os.listdir('.')]  # os.listdir可以列出文件和目录
# 内建的isinstance函数可以判断一个变量是不是字符串:
x = 'abc'
y = 123
print isinstance(x, str)
print isinstance(y, str)

'''
生成器
'''
# 列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?
# 这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
g = (x * x for x in range(10))
print g  # <generator object <genexpr> at 0x7f417e952280>
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
print g.next()   # 0
# print g.next()
'''
Traceback (most recent call last):
  File "./base/advanced.py", line 109, in <module>
    print g.next()   # 0
StopIteration
'''
'''
generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, …
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
'''


def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        print b
        a, b = b, a + b
        n = n + 1
fab(6)

# 仔细观察,可以看出,fab函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
# 也就是说,上面的函数和generator仅一步之遥。要把fab函数变成generator,只需要把print b改为yield b就可以了:


def fab1(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

print fab1(6)  # <generator object fab1 at 0x7fcc1c04f8c0>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值