美文网首页Python
Python学习(三)

Python学习(三)

作者: BlainPeng | 来源:发表于2017-01-25 17:26 被阅读22次

切片

我们要获取一个list或者tuple里面的元素,我们一般是通过for循环来获取的,但是要获取指定索引范围内的元素,用for循环的话略显繁琐,不过,Python给我们提供了切片(Slice)操作符

l = [1, 2, 3, 4, 5]
print(l[1:4])           # [2, 3, 4]
print(l[-4:-1])         # [2, 3, 4] 
print(l[2:])            # [3, 4, 5]

通过切片的方式获取的元素一般是包含头不包含尾

在Python中并没有提供像Java中对字符串进行截取的函数,不过,字符串可以通过切片来实现截取的功能

print("ABCDEFG"[2:5])       # CDE

迭代

我们之前通过for...in ..有对list和tuple进行循环,这种循环叫迭代(Iteration)。能够被迭代的对象,我们称之为迭代对象(Iterable),那么如何判断一个对象是否为Iterable了?还记得上篇文章有一个函数参数类型检查的吗?是的,就是通过isinstance函数来判断。

from collections import Iterable

print(isinstance("abc", Iterable))      # True
print(isinstance([], Iterable))         # True
print(isinstance((), Iterable))         # True
print(isinstance({}, Iterable))         # True
print(isinstance(123, Iterable))        # False

list的迭代比较简单,不过我们只能够获取元素,如果要获取list中元素的索引的话,需要借助enumerate函数;默认是从0开始的,当然也可以从自己指定数开始

l = ["手机", "电脑", "飞机", "火车"]
for index, value in enumerate(l):
    print(index, value)
print("-----------------")
for index, value in enumerate(l, 1):
    print(index, value)

打印结果:

0 手机
1 电脑
2 飞机
3 火车
-----------------
1 手机
2 电脑
3 飞机
4 火车

默认情况下,dict的迭代是key,我们也可以只迭代value,或者都迭代

d = {"1": "手机", "2": "电脑", "3": "飞机", "4": "火车"}
for key in d:
    print(key)
print("-----------------")
for value in d.values():
    print(value)
print("-----------------")
for key, value in d.items():
    print(key, value)

打印结果如下:

3
4
2
1
-----------------
飞机
火车
电脑
手机
-----------------
3 飞机
4 火车
2 电脑
1 手机

列表生成式

通过list函数可以生成一个list列表,如:

# range(start,stop,间隔数),根据间隔数获取指定范围内的数,默认为0
print(list(range(1, 11)))       # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

若要生成[1x1, 2x2, 3x3, ..., 10x10],可以这样写:

print(list(x * x for x in range(1, 11)))    # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

若只需要生成偶数的平方,可以这样写:

print(list(x * x for x in range(1, 11) if x % 2 == 0))      # [4, 16, 36, 64, 100]

for循环嵌套

print(list(m + n for m in "AB" for n in "CD"))      # ['AC', 'AD', 'BC', 'BD']

生成器(generator)

  • 作用
生成器是用来在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。
  • 创建方式

    • 把一个列表生成式的[]改成()

        g = (x * x for x in range(1, 11, 2))
        print(g)            # <generator object <genexpr> at 0x102184990>
        # 通过next函数来获取元素
        print(next(g))  # 1
        print(next(g))  # 9
        print(next(g))  # 25
        print(next(g))  # 49
        print(next(g))  # 81
        print(next(g))  # StopIteration
      

      当最后一个元素被计算出来后,再去计算下一个元素的话,会报一个StopIteration错误

    • 在函数定义中包含yield关键字

        def odd():
        print("step 1")
        yield 1
        print("step 2")
        yield 2
        print("step 3")
        yield 3
      

      获取元素:

        g = odd()
        print(g)
        print(next(g))
        print(next(g))
        print(next(g))
      

      打印结果如下:

        <generator object odd at 0x100784990>
        step 1
        1
        step 2
        2
        step 3
        3
      

      从打印结果可以看出,当第一次通过next函数获取元素时,由于遇到了yield,所以此时函数的执行就会被中断,将yield设定的值返回给调用者;然后第二次调用开始,此时程序会从上次中断的位置重新开始,继续执行代码,若又遇到yield,又会被中断,后面的就依此类推

  • 迭代生成器

    上面从生成器中去获取元素都是通过一个一个去调用next函数,很显然,这种变态的做法,我们程序员是不可能去做的。我们一般是通过for、while循环来获取的。还是以上面的odd函数为例。

      while True:
      try:
          r = next(g)
          print("g:", r)
      except StopIteration as e:
          print("Generator return value:", e.value)
          # 遇到StopIteration就退出循环
          break   
      
      # 打印结果如下:    
      g: 1
      g: 2
      g: 3
      Generator return value: None
          
      # 这里的try... except...类似于Java中的try...catch语句
    

迭代器(Iterator)

之前我们有学习到迭代对象,凡是可以被for循环的对象统称为可迭代对象(Iterable),当时是用isinstance函数来判断一个对象是否是可迭代对象。

可以被next函数调用并不断返回下一个值的对象称为迭代器(Iterator)。也可以用isinstance函数来判断哪些数据类型属于Iterator

from collections import Iterator

print(isinstance((x for x in range(1, 10)), Iterator))  # True
print(isinstance([], Iterator))                         # False
print(isinstance({}, Iterator))                         # False
print(isinstance("abc", Iterator))                      # False

虽然list,dict,str不是Iterator,但可以通过iter函数来进行转换

print(isinstance(iter(()), Iterator))                   # True

为什么list、dict、str等数据类型不是Iterator?

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

相关文章

网友评论

    本文标题:Python学习(三)

    本文链接:https://www.haomeiwen.com/subject/hhatittx.html