Python 容器切片,数组推倒,生成器

切片可以获取某个区间段的元素

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

# 切片
print(li[2:5])  # 2<= idx < 5 左闭右开
print(li[:4])   # 从第一个元素开始
print(li[5:])   # 到最后一个元素 
print(li[:])  # 全部输出
print(li[0:6:2])  # 2为步长
print(li[3::2])  # 到最后一个元素,且步长为2

#负数索引和step
print(li[::-1])  # 反向逐个元素输出,-1不能出现在冒号的左侧
print(li[::-2])  # 反向输出,步长为2
print(li[-6:-1:1])  # 反向输出   [5, 6, 7, 8, 9]
print(li[-1::-1])  # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 等同 li[::-1]
print(li[-1::])  # 这里仅输出一个元素 10


# 一维数组
print([i * 2 for i in range(10)]) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
print([i * i for i in range(10) if (i % 3) == 0])  # [0, 9, 36, 81]
print([(x, y) for x in range(3) for y in range(3)])  # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

# 二维数组
a = [[3] * (i + 1) for i in range(3)]  # [[3], [3, 3], [3, 3, 3]]
print(a[2])  # [3, 3, 3]

# 乘法的问题
a = [[1, 2, 3]] *3  # [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 等于直接将原来的数组出现三次,我理解,这三个数组的性质应该都一样
a[1][1] = 100  # [[1, 100, 3], [1, 100, 3], [1, 100, 3]]  这里会出现错误,都被修改成了100
print(a)  # 

# 解决方法(正确的写法)
a = [[1, 2, 3] for i in range(3)] # [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
a[1][1] = 100  # [[1, 2, 3], [1, 100, 3], [1, 2, 3]]
print(a)

# 生成器
# 简单方法
x = range(10)
print(type(x))  # <type'list'>
sx = (x * x for x in range(10))
print(type(x))  # <type'generator'> 如果是[]在外面,则直接生成list
# 然后利用函数进行循环输出
'''
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
print(next(sx))
'''

for i in sx:
    print(i)  #  依次进行输出
# 生成器生成fib数列
def fib(limit):
   n, a, b = 0, 0, 1
   while n < limit:  # 注意此处是小于
        yield b  # 生成值
        a, b = b, a + b
        n += 1
   return 'done'
for i in fib(10):
    print(i)
# 输出
1
1
2
3
5
8
13
21
34
55
1
这里我们看下yield生成器的用法:
任何使用yield函数都称为生成器,是一个返回迭代器的函数,使用yield,可以让函数生成一个序列
该函数返回的对象是"generator",通过该对象连续调用netx()方法返回序列值。
#生成器
def count(n):
      while n > 0:
          yield n    # 生成值 n
          n -= 1

# 调用,此时不输出内容,生成器只有在调用next()等执行操作的时候,才会有输出
c = count(5)
# 第一次调用,在第一次碰见yield处停止,此处n为5
c.next()  # 输出5
# 第二次调用 , 在上次碰见yield地方,即n=5的地方,继续执行 n -= 1,然后等再次碰见yield的时候,停止。
c.next()  # 输出4
为了更加直观的看到执行步骤,详细见以下代码:
def count(n):
    print("counting")
    while n > 0:
       print('before yield')
       yield n
       n -= 1
       print('after yield')
输出:
>>> c.next()
counting
before yield
5
>>> c.next()
after yield
before yield
4
>>> c.next()
after yield
before yield
3

在清楚了以上的执行顺序的后,我们用print()来进行循环输出
>>> for i in count(5):
...     print(i)
... 
counting
before yield
5
after yield
before yield
4
after yield
before yield
3
after yield
before yield
2
after yield
before yield
1
after yield











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值