Python系列(3)- Python 数据类型、推导式、迭代器与生成器

 

1. 数据类型

    Python3 中有六个基本的数据类型:

        不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
        可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

    可以使用内置的 type() 函数可以用来查询变量所指的对象类型,也可以使用 isinstance。isinstance 和 type 的区别在于:

        type() 不会认为子类是一种父类类型。
        isinstance() 会认为子类是一种父类类型。


    1) Number(数字)

        Python3 支持 int、float、bool、complex(复数)。
        
        在 Python3 中,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
        
        在 Python3 中,bool 是 int 的子类,True 和 False 可以和数字相加,True==1、False==0 会返回 True。

        complex(复数)由实数部分和虚数部分构成,可以用 a + bj,或者 complex(a,b) 表示, 复数的实部 a 和虚部 b 都是浮点型。
        
        使用 del 语句删除对象引用,语法格式:

            del var1[,var2[,var3[....,varN]]]
       

        示例:

            #!/usr/bin/python3

            a, b, c, d = 20, 5.5, True, 4+3j

            print('type(a), type(b), type(c), type(d): ', type(a), type(b), type(c), type(d))
            print('isinstance(a, int): ', isinstance(a, int))
            print()

            # 类型判断
            class A:
                pass

            class B(A):
                pass

            print('isinstance(A(), A): ', isinstance(A(), A))
            print('type(A()) == A): ', type(A()) == A))
            print('isinstance(B(), A): ', isinstance(B(), A))
            print('type(B()) == A: ', type(B()) == A)
            print()

            # 布尔型
            print('issubclass(bool, int): ', issubclass(bool, int))
            print('True==1: ', True==1)
            print('False==0: ', False==0)
            print('True+1: ', True+1)
            print('False+1: ', False+1)
            print()

            # 数值运算
            print('3 + 7: ', 3 + 7)
            print('4.6 - 2: ', 4.6 - 2)    # 在混合计算时,Python 会把整型转换成为浮点数
            print('3 * 5: ', 3 * 5)
            print('5 / 2: ', 5 / 2)     # 除法,得到一个浮点数
            print('5 // 2: ', 5 // 2)   # 除法,得到一个整数
            print('17 % 3: ', 17 % 3)
            print('2 ** 3: ', 2 ** 3)
            print()

            del a,b
            print('del -> a:', a)


        输出结果如下:

            type(a), type(b), type(c), type(d):  <class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
            isinstance(a, int):  True

            isinstance(A(), A):  True
            type(A()) == A):  True
            isinstance(B(), A):  True
            type(B()) == A:  False

            issubclass(bool, int):  True
            True==1:  True
            False==0:  True
            True+1:  2
            False+1:  1

            3 + 7:  10
            4.6 - 2:  2.5999999999999996
            3 * 5:  15
            5 / 2:  2.5
            5 // 2:  2
            17 % 3:  2
            2 ** 3:  8

            Traceback (most recent call last):
            File "data_type.py", line 42, in <module>
                print('del -> a:', a)
            NameError: name 'a' is not defined


    2) String(字符串)

        Python 中的字符串用单引号 ' 或双引号 " 括起来,使用反斜杠 \ 转义特殊字符,不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串。

        反斜杠 \ 可以作为续行符,表示下一行是上一行的延续。也可以使用 """...""" 或者 '''...''' 跨越多行。

        Python 没有单独的字符类型,一个字符就是长度为 1 的字符串,字符串内的字符不能修改,整个字符串可以重新赋值。

        字符串的截取的语法格式如下:

            变量[头下标:尾下标]
            索引值以 0 为开始值,-1 为从末尾的开始位置。

        加号 + 是字符串的连接符,星号 * 表示复制当前字符串,与之结合的数字为复制的次数。

               
        示例:

            #!/usr/bin/python3

            str = 'python string'
            str2 = 'pytho\n string'
            str3 = r'pytho\n string'

            print("str: ", str)                # 输出字符串
            print("str[0:-1]: ", str[0:-1])    # 输出第一个到倒数第二个的所有字符
            print("str[0]: ", str[0])          # 输出字符串第一个字符
            print("str[2:5]: ", str[2:5])      # 输出从第三个开始到第五个的字符
            print("str[2:]: ", str[2:])        # 输出从第三个开始的后的所有字符
            print("str * 2: ", str * 2)        # 输出字符串两次,也可以写成 print (2 * str)
            print("str + ' connect': ", str + " connect") # 连接字符串

            str = 'new string'
            print("str2: ", str2)
            print("str3: ", str3)
            print("str: ", str)


        输出结果如下:

            str:  python string
            str[0:-1]:  python strin
            str[0]:  p
            str[2:5]:  tho
            str[2:]:  thon string
            str * 2:  python stringpython string
            str + ' connect':  python string connect
            str2:  pytho
             string
            str3:  pytho\n string
            str:  new string   

  
    3) List(列表)

        List(列表) 是 Python 中使用最频繁的数据类型。

        列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。

        列表截取的语法格式如下:

            变量[头下标:尾下标]
            索引值以 0 为开始值,-1 为从末尾的开始位置。

        加号 + 是列表连接运算符,星号 * 是重复操作。

        格式:

            l = [ value1, value2, ... ]


        示例:

            #!/usr/bin/python3

            l1 = [ 'abcd', 456 , 100.07, 'test', 6.99 ]
            l2 = [ 123, 'good' ]

            print("l1: ", l1)               # 输出完整列表
            print("l1[0]: ", l1[0])         # 输出列表第一个元素
            print("l1[1:3]: ", l1[1:3])     # 从第二个开始输出到第三个元素
            print("l1[2:]: ", l1[2:])       # 输出从第三个元素开始的所有元素
            print("l2 * 2: ", l2 * 2)       # 输出两次列表
            print("l1 + l2: ", l1 + l2)     # 连接列表

            l1[1] = 'replaced'
            print("l1: ", l1)


        输出结果如下:

            l1:  ['abcd', 456, 100.07, 'test', 6.99]
            l1[0]:  abcd
            l1[1:3]:  [456, 100.07]
            l1[2:]:  [100.07, 'test', 6.99]
            l2 * 2:  [123, 'good', 123, 'good']
            l1 + l2:  ['abcd', 456, 100.07, 'test', 6.99, 123, 'good']
            l1:  ['abcd', 'replaced', 100.07, 'test', 6.99]


    4) Tuple(元组)

        元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开,元组中的元素类型可以不相同。

        元组与字符串类似,可以被索引且下标索引从 0 开始,-1 为从末尾开始的位置,可以把字符串看作一种特殊的元组。
        
        元组的元素不能修改,但它可以包含可变的对象(比如 list 列表)。元组也可以被索引和切片,方法和列表一样。元组也可以使用 + 操作符进行拼接。

        格式:

            t = ( value1, value2, ...)

        示例:

            #!/usr/bin/python3

            t1 = ( 'abcd', 456 , 100.07, 'test', 6.99 )
            t2 = ( 123, 'good' )

            print("t1: ", t1)             # 输出完整元组
            print("t1[0]: ", t1[0])       # 输出元组的第一个元素
            print("t1[1:3]: ", t1[1:3])   # 输出从第二个元素开始到第三个元素
            print("t1[2:]: ", t1[2:])     # 输出从第三个元素开始的所有元素
            print("t2 * 2: ", t2 * 2)     # 输出两次元组
            print("t1 + t2: ", t1 + t2)   # 连接元组

 

        输出结果如下:

            t1:  ('abcd', 456, 100.07, 'test', 6.99)
            t1[0]:  abcd
            t1[1:3]:  (456, 100.07)
            t1[2:]:  (100.07, 'test', 6.99)
            t2 * 2:  (123, 'good', 123, 'good')
            t1 + t2:  ('abcd', 456, 100.07, 'test', 6.99, 123, 'good')


        构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:

            tup1 = ()       # 空元组
            tup2 = (20,)    # 一个元素,需要在元素后添加逗号

        string、list 和 tuple 都属于 sequence(序列)。

    5) Set(集合)

        集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。

        基本功能是进行成员关系测试和删除重复元素。

        可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

        格式:

            s = {value1, value2, ...}

        或
            set(value)

        示例:

            #!/usr/bin/python3

            sites = {'Google', 'Taobao', 'Zhihu', 'Baidu'}

            print("sites: ", sites)   # 输出集合,重复的元素被自动去掉

            if 'Taobao' in sites :
                print('Taobao 在集合中')
            else :
                print('Taobao 不在集合中')

            a = set('abracadabra')
            b = set('alacazam')
            c = set(['abc', 'edf', 'xyz'])

            print("a: ", a)
            print("a - b: ", a - b)     # a 和 b 的差集
            print("a | b: ", a | b)     # a 和 b 的并集
            print("a & b: ", a & b)     # a 和 b 的交集
            print("a ^ b: ", a ^ b)     # a 和 b 中不同时存在的元素
            print("c: ", c)


        输出结果如下:

            sites:  {'Baidu', 'Google', 'Zhihu', 'Taobao'}
            Taobao 在集合中
            a:  {'r', 'b', 'a', 'd', 'c'}
            a - b:  {'r', 'd', 'b'}
            a | b:  {'m', 'r', 'b', 'z', 'a', 'l', 'd', 'c'}
            a & b:  {'c', 'a'}
            a ^ b:  {'b', 'm', 'z', 'l', 'r', 'd'}
            c:  {'xyz', 'abc', 'edf'}


    6) Dictionary(字典)

        列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

        字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。

        键 (key) 必须使用不可变类型,在同一个字典中,键(key)必须是唯一的。

        格式:

            d = {key1 : value1, key2 : value2, key3 : value3, ... }
        
        或
        
            d = dict(value1=key1, value2=key2, value3=key3, ... )

        示例:

            #!/usr/bin/python3

            d1 = {}       # 空字典
            d1['one'] = "1 - 字典"
            d1[2]     = "2 - 类型"

            d2 = {'name': 'test', 'code':1, 'site': 'www.test.com'}

            d3 = dict(Baidu=1, Google=2, Taobao=3)
            d4 = dict([('Baidu', 1), ('Google', 2), ('Taobao', 3)])

            print('d1[\'one\']: ', d1['one'])       # 输出键为 'one' 的值
            print('d1[2]: ', d1[2])                 # 输出键为 2 的值
            print('d2: ', d2)                       # 输出完整的字典
            print('d2.keys(): ', d2.keys())         # 输出所有键
            print('d2.values(): ', d2.values())     # 输出所有值

            print('d3: ', d3)
            print('d4: ', d4)


        输出结果如下:

            d1['one']:  1 - 字典
            d1[2]:  2 - 类型
            d2:  {'name': 'test', 'code': 1, 'site': 'www.test.com'}
            d2.keys():  dict_keys(['name', 'code', 'site'])
            d2.values():  dict_values(['test', 1, 'www.test.com'])
            d3:  {'Baidu': 1, 'Google': 2, 'Taobao': 3}
            d4:  {'Baidu': 1, 'Google': 2, 'Taobao': 3}

 


2. 推导式

    Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。

    Python 支持各种数据结构的推导式:

        列表(list)推导式
        字典(dict)推导式
        集合(set)推导式
        元组(tuple)推导式

    1) 列表(list)推导式

        格式:

            [表达式 for 变量 in 列表]
            [out_exp_res for out_exp in input_list]

        或

            [表达式 for 变量 in 列表 if 条件]
            [out_exp_res for out_exp in input_list if condition]

        out_exp_res:列表生成元素表达式,可以是有返回值的函数。
        for out_exp in input_list:迭代 input_list 将 out_exp 传入到 out_exp_res 表达式中。
        if condition:条件语句,可以过滤列表中不符合条件的值。

        示例:

            #!/usr/bin/python3

            # 过滤掉长度 <= 3 的字符串列表,并将剩下的转换成大写字母
            names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
            new_names = [name.upper() for name in names if len(name)>3]
            print(new_names)

            # 计算 30 以内可以被 3 整除的整数
            multiples = [i for i in range(30) if i % 3 == 0]
            print(multiples)


        输出结果如下:

            ['ALICE', 'JERRY', 'WENDY', 'SMITH']
            [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

    2) 字典(dict)推导式

        格式:

            { key_expr: value_expr for value in collection }

        或

            { key_expr: value_expr for value in collection if condition }

        示例:

            #!/usr/bin/python3

            # 使用字符串及其长度创建字典
            listdemo = ['Google','Baidu', 'Taobao']
            newdict = {key:len(key) for key in listdemo}
            print(newdict)

            # 提供三个数字,以三个数字为键,三个数字的平方为值来创建字典
            dic = {x: x**2 for x in (2, 4, 6)}
            print(dic)
            print(type(dic))


        输出结果如下:

            {'Google': 6, 'Baidu': 6, 'Taobao': 6}
            {2: 4, 4: 16, 6: 36}
            <class 'dict'>

    3) 集合(set)推导式

        格式:

            { expression for item in Sequence }
        或

            { expression for item in Sequence if conditional }

        示例:

            #!/usr/bin/python3

            # 计算数字 1,2,3 的平方数
            setnew = {i**2 for i in (1,2,3)}
            print(setnew)

            # 判断不是 abc 的字母并输出
            a = {x for x in 'abracadabra' if x not in 'abc'}
            print(a)
            print(type(a))


        输出结果如下:

            {1, 4, 9}
            {'d', 'r'}
            <class 'set'>

    4) 元组(tuple)推导式

        元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。

        格式:

            (expression for item in Sequence )

        或

            (expression for item in Sequence if conditional )

        元组推导式和列表推导式的用法也完全相同,只是元组推导式是用 () 圆括号将各部分括起来,而列表推导式用的是中括号 [],另外元组推导式返回的结果是一个生成器对象。


        示例,生成一个包含数字 1~9 的元组:

            #!/usr/bin/python3

            a = (x for x in range(1,10))
            print(a)   # a 是生成器对象
            print(tuple(a))     # 使用 tuple() 函数,可以直接将生成器对象转换成元组

 

        输出结果如下:

            <generator object <genexpr> at 0x7faf6ee20a50>
            (1, 2, 3, 4, 5, 6, 7, 8, 9)


3. 迭代器与生成器

    1) 迭代器

        迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

        字符串,列表或元组对象都可用于创建迭代器。迭代器有两个基本的方法:iter() 和 next()。

        迭代器对象可以使用常规 for 语句进行遍历,示例:

            #!/usr/bin/python3
            
            list=[1,2,3,4]
            it = iter(list)
            for x in it:
                print (x, end=" ")


        输出结果如下:

            1 2 3 4

        也可以使用 next() 函数,示例:

            #!/usr/bin/python3
            
            import sys
            
            list=[1,2,3,4]
            it = iter(list)
            
            while True:
                try:
                    print (next(it), end=" ")
                except StopIteration:
                    sys.exit()


        输出结果如下:

            1 2 3 4

    2) 自定义迭代器

        把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

        __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。

        __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。

        示例,创建一个返回数字的迭代器,初始值为 1,逐步递增 1:

            #!/usr/bin/python3

            class MyNumbers:
              def __iter__(self):
                  self.a = 1
                  return self
            
              def __next__(self):
                  x = self.a
                  self.a += 1
                  return x
            
            myclass = MyNumbers()
            myiter = iter(myclass)
            
            print(next(myiter))
            print(next(myiter))
            print(next(myiter))
            print(next(myiter))


        执行输出结果为:

            1
            2
            3
            4

    3) StopIteration

        StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

        示例,在 10 次迭代后停止执行:

            #!/usr/bin/python3

            class MyNumbers:
            def __iter__(self):
                self.a = 1
                return self
            
            def __next__(self):
                if self.a <= 10:
                x = self.a
                self.a += 1
                return x
                else:
                raise StopIteration
            
            myclass = MyNumbers()
            myiter = iter(myclass)
            
            for x in myiter:
            print (x, end=" ")

 

        执行输出结果为:

            1 2 3 4 5 6 7 8 9 10

    4) 生成器

        在 Python 中,使用了 yield 的函数被称为生成器(generator)。

        跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

        在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

        调用一个生成器函数,返回的是一个迭代器对象。

        示例,使用 yield 实现斐波那契数列:

            #!/usr/bin/python3
            
            import sys
            
            def fibonacci(n):   # 生成器函数
                a, b, counter = 0, 1, 0
                while True:
                    if (counter > n):
                        return
                    yield a
                    a, b = b, a + b
                    counter += 1

            f = fibonacci(10)   # f 是一个迭代器,由生成器返回生成
            
            while True:
                try:
                    print (next(f), end=" ")
                except StopIteration:
                    sys.exit()


        输出结果如下:

            0 1 1 2 3 5 8 13 21 34 55


posted @ 2022-10-25 18:17  垄山小站  阅读(150)  评论(0)    收藏  举报