zoukankan      html  css  js  c++  java
  • python基础归结

    #!/usr/bin/env python3
    # -*- encoding: utf-8 -*-
    
    print('Hello world')
    print('中国心')

    python程序本质是脚本语言,与shell相同,都是顺序逐条语句执行,语句执行完成后退出。没有main函数。

    00.python程序格式

    #开头的语句是注释,其他每一行都是一个语句。

    语句以冒号(:)结尾时,缩进的语句视为代码块(没有C语言中{}区分代码块)。

    约定俗称, 4个空格缩进,Tab或空格均可以,但要保持一致。

    python大小写敏感。

    0.unicode&utf-8

    在计算机内存中,统一使用unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为utf-8编码。

    用记事本编辑的时候,从文件读取的utf-8字符被转换为unicode字符到内存里,编码完成保存时再把unicode转换为utf-8保存到文件。

    浏览网页时,服务器会把动态生成的unicode内容转换为utf-8再传输给浏览器,所以会看到许多网页的源码上会有类似<meta charset="UTF-8" />的信息,表示该网页正是用的utf-8编码。

    1. 除法

    Python中有两种除法,一种除法是/,/除法计算结果永远是浮点数。

    地板除//,计算结果永远是整数。

    余数运算%。

    无论整数做//除法还是取余数,结果永远是整数,所以,整数运算结果永远是精确的。

    2. 布尔值类型

    布尔值类型只有Truce、False两种值(注意Python大小写敏感)。

    布尔值可以用and,or,和not运算。

    3. 空值

    空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

    4. 常量

    在Python中,通常用全部大写的变量名表示常量。

    5. bytes类型

    Python对bytes类型的数据用带b前缀的单引号或双引号表示:

    x=b'ABC'

    要注意区分'ABC'b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字符都只占用一个字节。

    纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。

    bytes中,无法显示为ASCII字符的字节,用x##显示。

    b''(b前缀):每个字节占用一个字节。print(b'A A') ---b'A A'

    u''(u前缀)或无前缀:字符串默认以Unicode编码存储,可以存储中文。Unicode中每个字符占用两个字节。print(u'A A') ---A  A

    r''(r前缀):主要解决转义字符、特殊字符问题,其中所有字符均被视为普通字符。print(r'A A')--A A

    6. str和bytes转换

    由于Python的字符串类型是str,在内存中以unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes。以unicode表示的str通过encode()方法可以编码为指定的bytes;反过来,从网络或磁盘上读取了字节流,读取到的数据是bytes,用decode()将bytes变为str。

    在操作字符串时,我们经常遇到strbytes的互相转换。为了避免乱码问题,应当始终坚持使用UTF-8编码对strbytes进行转换。

    >>> '中文'.encode('utf-8')
    b'xe4xb8xadxe6x96x87'
    >>> b'xe4xb8xadxe6x96x87'.decode('utf-8')
    '中文'
    >>> '33345'.encode('utf-8')
    b'33345'
    >>> '中8'.encode('utf-8')
    b'xe4xb8xad8'
    >>> b'xe4xb8xad8'.decode('ascii')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
    >>> b'xe4xb8xad8'.decode('utf-8')
    '中8'

    7. 输入输出

    输入用input(),输出用print()。

    input()可以输入提示字符串,input()返回的数据类型是str,str不能直接和整数比较。

    >>> name=input('please enter your name:')
    please enter your name:wang
    >>> print('hello,', name)
    hello, wang
    >>> job="IT"
    >>> print('hello', name, job)
    hello wang IT

    8. 格式化

    %运算符用来格式化字符串。

    %用来分割格式化子串和格式化参数,多个格式化参数时要用括号包围。

    在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或值,顺序要对应好。如果只有一个%?,括号可以忽略。

    >>> 'Hello, %s' % 'world'
    'Hello, world'
    >>> 'Hi, %s, you have $%d' % ('Michael', 100000)
    'Hi, Michael, you have $100000'
    >>> print('Hi, %s, you have $%d', 'Michael', 10000)
    Hi, %s, you have $%d Michael 10000
    >>> print('Hi, %s, you have $%d' % 'Michael', 10000)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: not enough arguments for format string
    >>> print('Hi, %s, you have $%d' % ('Michael', 10000))
    Hi, Michael, you have $10000

    注:必须用%分割格式化子串和参数,不能像C语言一样用逗号(,),否则后面的参数被作为字符串处理(字符串拼接)。

    9.数组和元组

    list是一种有序的集合,就是数组([])。索引从0开始,可用-1获取最后一个元素。

    可用len()获取list元素个数。

    list支持的函数append(element)insertindexelement),pop(),popindex)。

    list里元素类型可以不同,可以内嵌另一个list,支持二维数组、三维数组……

    tuple是元组,一旦初始化就不能修改,用()标识。

    tuple没有append()insert()方法,因为它不支持修改元素。

    tuple的陷阱:当定义一个tuple时,tuple的元素就必须被确定下来。

    定义一个空的tuple,可以写成(),如t=()

    定义只有一个元素的tuple,需写成(1,),如t=(3,),而不能是t=(3)这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是3。所以,只有1个元素的tuple定义时必须加一个逗号,,来消除歧义。

    >>> t=(3,)
    >>> t
    (3,)
    >>> t=(3)
    >>> t
    3

    看一个可变tuple的例子:

    >>> t = ('a', 'b', ['A', 'B'])
    >>> t[2][0] = 'X'
    >>> t[2][1] = 'Y'
    >>> t
    ('a', 'b', ['X', 'Y'])

    t是一个元组,内嵌一个list,内嵌的list地址不变,变得是list指向的存储的内容。

    tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!

    理解了“指向不变”后,要创建一个内容也不变的tuple怎么做?那就必须保证tuple的每一个元素本身也不能变。

    10.条件判断

    if <条件判断1>:
        <执行1>
    elif <条件判断2>:
        <执行2>
    elif <条件判断3>:
        <执行3>
    else:
        <执行4>
    if判断条件还可以简写,比如写:
    if x:
        print('True')

    只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False

    11.循环

    for x in ...循环就是把每个元素代入变量x,然后执行缩进块的语句。

    sum = 0
    for x in range(101):
        sum = sum + x
    print(sum)

    如果要计算1-100的整数之和,从1写到100有点困难,幸好Python提供一个range()函数,可以生成一个整数序列,再通过list()函数可以转换为list

    python也支持while循环和break/continue:

    n = 1
    while n <= 100:
        if n > 10: # 当n = 11时,条件满足,执行break语句
            break # break语句会结束当前循环
        print(n)
        n = n + 1
    print('END')
    n
    = 0 while n < 10: n = n + 1 if n % 2 == 0: # 如果n是偶数,执行continue语句 continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行 print(n)

    break语句可以在循环过程中直接退出循环,而continue语句可以提前结束本轮循环,并直接开始下一轮循环。这两个语句通常都必须配合if语句使用。

    12. dict

    python内置了字典:dict的支持,dictionary,用{}标识。在其他语言中也称为map,使用key-value存储,具有极快的查找速度。一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉。dictkey必须是不可变对象。字符串、整数等都是不可变的,list是可变的,因此list不能用作key

    >>> d={'wang':100,'chen':120,'zhang':130}
    >>> d['wang']
    100
    >>> d
    {'wang': 100, 'chen': 120, 'zhang': 130}
    >>> d['zhang']=140
    >>> d
    {'wang': 100, 'chen': 120, 'zhang': 140}
    >>> d['xue']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    KeyError: 'xue'
    >>> d={'wang':100,'chen':120,'zhang':130}
    >>> d
    {'chen': 120, 'zhang': 130, 'wang': 100}
    >>> d['xu']=130
    >>> d
    {'chen': 120, 'xu': 130, 'zhang': 130, 'wang': 100}

    判断key是否在dict中有两种方法:1key in dict2get(),如果key不存在,返回None,或者自己指定的value

    >>> 'wang' in d
    True
    >>> xue in d
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'xue' is not defined
    >>> wang in d
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'wang' is not defined
    >>> d.get('wang')
    100
    >>> d.get('xue')
    >>>

    注意:返回None的时候Python的交互环境不显示结果。

    删除一个keypop(key):

    100
    >>> d
    {'chen': 120, 'zhang': 140}

    请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

    13set

    set也是一个key的集合,但不存储value。由于key不能重复,所以在set中,没有重复的key

    要创建一个set,需要提供一个list作为输入集合:

    >>> s = set([1, 2, 3])
    >>> s
    {1, 2, 3}

    注意,传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1233个元素,显示的顺序也不表示set是有序的。

    通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果。通过remove(key)方法可以删除元素。

    >>> s.add(4)
    >>> s
    {1, 2, 3, 4}
    >>> s.add(4)
    >>> s
    {1, 2, 3, 4}

    set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

    >>> s1 = set([1, 2, 3])
    >>> s2 = set([2, 3, 4])
    >>> s1 & s2
    {2, 3}
    >>> s1 | s2
    {1, 2, 3, 4}

    setdict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。

    14. 切片

    切片是提取一个listtuple的部分元素。

    1)切片用冒号界定区间,L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引012,正好是3个元素。

    2)如果第一个索引是0,还可以省略。

    3[:]就可以原样复制一个list

    4)切片可以进一步过滤条件,若[:10:2]表示前10个数每两个取一个,[::5]所有数每5个取一个。

    5Python支持L[-1]取倒数第一个元素,python同样支持倒数切片。

    >>> L=list(range(100))
    >>> L
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
    >>> L[::5]
    [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
    >>> L[-10:]
    [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
    >>> L[::10]
    [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
    >>> L[30:40]
    [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]

    tuple和字符串同样适合切片提取元素。

    15.迭代iterate

    python中迭代通过for…in来实现。

    listtuppledictsetstr都可以迭代。

    dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代keyvalue,可以用for k, v in d.items()

    >>> d={'a':1, 'b':2, 'c':3, 'd':4}
    >>> for key in d:
    ...     print(key)
    ... 
    a
    b
    d
    c
    >>> for k,v in d.items():
    ...     print('%s is %d' %(k,v))
    ... 
    a is 1
    b is 2
    d is 4
    c is 3

    如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断

    >>> from collections import Iterable
    >>> isinstance('abc', Iterable) # str是否可迭代
    True
    >>> isinstance([1,2,3], Iterable) # list是否可迭代
    True
    >>> isinstance(123, Iterable) # 整数是否可迭代
    False

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

    >>> for i,t in enumerate([(1,1),(2,4),(3,9)]):
    ...     print(i, t)
    ... 
    0 (1, 1)
    1 (2, 4)
    2 (3, 9)

    16list comprehensions列表生成式

    写列表生成式时,就是把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来。

    >>> LL=[x*x for x in range(10)]
    >>> LL
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

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

    >>> LL=[x*x for x in range(10) if x%2==0]
    >>> LL
    [0, 4, 16, 36, 64]

    还可以使用两层循环,可以生成全排列:

    >>> [m+n for m in 'abc' for n in 'XYZ']
    ['aX', 'aY', 'aZ', 'bX', 'bY', 'bZ', 'cX', 'cY', 'cZ']

    17.生成器

    通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表的容量是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。一边循环一边计算的机制,称为生成器generatorgenerator有两种实现方式:列表生成式或函数。

    基于list comprehensionsgenerator

    只要把一个列表生成式的[]改成(),就创建了一个generator

    >>> L = [x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x1022ef630>

    创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator

    通过next(g)可以一个一个地打印generator的值。

    generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

    >>> g=(x*x for x in range(2))
    >>> next(g)
    0
    >>> next(g)
    1
    >>> next(g)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration

    对于generator,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。 

    基于函数的generator

    如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'

    最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

    18.迭代器

    可以直接作用于for循环的数据类型有以下几种:

    一类是集合数据类型,如listtupledictsetstr等;

    一类是generator,包括生成器和带yieldgenerator function

    这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。可以使用isinstance()判断一个对象是否是Iterable对象:

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)), Iterator)
    True
    >>> isinstance([], Iterator)
    False
    >>> isinstance({}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    False

    生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

    listdictstrIterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)
    True
    >>> LLL=list(range(5))
    >>> IT=iter(LLL)
    >>> IT
    <list_iterator object at 0x7f454b9abb38>
    >>> next(IT)
    0
    >>> for x in IT:
    ...     print(x)
    ... 
    1
    2
    3
    4

    为什么listdictstr等数据类型不是Iterator

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

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

      

    参考:

    1. 廖雪峰python教程之字符串和编码

    2. https://naveenr.net/unicode-character-set-and-utf-8-utf-16-utf-32-encoding/

    3. Python成长之路

  • 相关阅读:
    函数的定义
    函数加载的过程
    js中的return
    快速排序
    冒泡排序
    数组的案例
    正睿暑期培训day3考试
    bzoj2115 Xor
    luogu4570 元素
    bzoj4827 Hnoi2017 礼物
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/9822563.html
Copyright © 2011-2022 走看看