码迷,mamicode.com
首页 > 编程语言 > 详细

Python(一)

时间:2018-11-17 16:16:25      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:rip   inter   偶数   运行   浅拷贝   布尔   quit   ppi   除法   

python

基本数据运算符

算术运算符

运算符 描述 实例(a=10,b=20)
+ 加 - 两个对象相加 a + b 输出结果 30
- 减 - 得到负数或是一个数减去另一个数 a - b 输出结果 -10
* 乘 - 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200
/ 除 - x除以y b / a 输出结果 2
% 取模 - 返回除法的余数 b % a 输出结果 0
** 幂 - 返回x的y次幂 a**b 为10的20次方, 输出结果 100000000000000000000
// 取整除 - 返回商的整数部分(向下取整 >>> 9//2 4
>>> -9//2 -5

位运算符

运算符 描述 实例
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101
^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式。
<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000
>> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111

逻辑运算符

运算符 逻辑表达式 描述 实例
and x and y 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 (a and b) 返回 20。
or x or y 布尔"或" - 如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。 (a or b) 返回 10。
not not x 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 not(a and b) 返回 False

赋值运算符

运算符 描述 实例
= 简单的赋值运算符 c = a + b 将 a + b 的运算结果赋值为 c
+= 加法赋值运算符 c += a 等效于 c = c + a
-= 减法赋值运算符 c -= a 等效于 c = c - a
*= 乘法赋值运算符 c = a 等效于 c = c a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符 c %= a 等效于 c = c % a
**= 幂赋值运算符 c = a 等效于 c = c a
//= 取整除赋值运算符 c //= a 等效于 c = c // a

比较运算符

运算符 描述 实例
== 等于 - 比较对象是否相等 (a == b) 返回 False。
!= 不等于 - 比较两个对象是否不相等 (a != b) 返回 true.
<> 不等于 - 比较两个对象是否不相等 (a <> b) 返回 true。这个运算符类似 != 。
> 大于 - 返回x是否大于y (a > b) 返回 False。
< 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。 (a < b) 返回 true。
>= 大于等于 - 返回x是否大于等于y。 (a >= b) 返回 False。
<= 小于等于 - 返回x是否小于等于y。 (a <= b) 返回 true。

成员运算符

运算符 描述 实例
in 如果在指定的序列中找到值返回 True,否则返回 False。 x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。 x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。

身份运算符

算符 描述 实例
is is 是判断两个标识符是不是引用自一个对象 x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is not is not 是判断两个标识符是不是引用自不同对象 x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。

基本数据类型

数字

int(整型)

  在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647
  在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1,即-9223372036854775808~9223372036854775807
数字:
python的数字运算,包括了(加:+,减:-,乘:*;除: / ;双星号:**)等。

    >>> a = 123
    >>> b = 456
    >>> a * b
    56088
    >>> a / b
    0.26973684210526316
    >>> a%b
    123
    >>> a // b
    0
    >>> a + b
    579
    >>> a ** 2
    15129
    >>> len(str(2**100))
    31
    >>> 123.345 ** 2
    15213.989024999999
    >>> print(123.345 ** 2)
    15213.989024999999
    >>> 12.34 * 2
    24.68
    >>> import math
    >>> math.pi
    3.141592653589793
    >>> math.sqrt(2)
    1.4142135623730951
    >>>
    >>> import random
    >>> random.random()
    0.9013111518954912
    >>> random.random()
    0.037732894432051745
    >>> random.random()
    0.8587096319039393
    >>>
int

        class int(object):
        """
        int(x=0) -> int or long
        int(x, base=10) -> int or long
    
        Convert a number or string to an integer, or return 0 if no arguments
        are given.  If x is floating point, the conversion truncates towards zero.
        If x is outside the integer range, the function returns a long instead.
    
        If x is not a number or if base is given, then x must be a string or
        Unicode object representing an integer literal in the given base.  The
        literal can be preceded by ‘+‘ or ‘-‘ and be surrounded by whitespace.
        The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to
        interpret the base from the string as an integer literal.
        >>> int(‘0b100‘, base=0)
        """
        def bit_length(self):
        """ 返回表示该数字的时占用的最少位数 """
        """
        int.bit_length() -> int
    
        Number of bits necessary to represent self in binary.
        >>> bin(37)
        ‘0b100101‘
        >>> (37).bit_length()
        """
        return 0
    
        def conjugate(self, *args, **kwargs): # real signature unknown
        """ 返回该复数的共轭复数 """
        """ Returns self, the complex conjugate of any int. """
        pass
    
        def __abs__(self):
        """ 返回绝对值 """
        """ x.__abs__() <==> abs(x) """
        pass
    
        def __add__(self, y):
        """ x.__add__(y) <==> x+y """
        pass
    
        def __and__(self, y):
        """ x.__and__(y) <==> x&y """
        pass
    
        def __cmp__(self, y):
        """ 比较两个数大小 """
        """ x.__cmp__(y) <==> cmp(x,y) """
        pass
    
        def __coerce__(self, y):
        """ 强制生成一个元组 """
        """ x.__coerce__(y) <==> coerce(x, y) """
        pass
    
        def __divmod__(self, y):
        """ 相除,得到商和余数组成的元组 """
        """ x.__divmod__(y) <==> divmod(x, y) """
        pass
    
        def __div__(self, y):
        """ x.__div__(y) <==> x/y """
        pass
    
        def __float__(self):
        """ 转换为浮点类型 """
        """ x.__float__() <==> float(x) """
        pass
    
        def __floordiv__(self, y):
        """ x.__floordiv__(y) <==> x//y """
        pass
    
        def __format__(self, *args, **kwargs): # real signature unknown
        pass
    
        def __getattribute__(self, name):
        """ x.__getattribute__(‘name‘) <==> x.name """
        pass
    
        def __getnewargs__(self, *args, **kwargs): # real signature unknown
        """ 内部调用 __new__方法或创建对象时传入参数使用 """
        pass
    
        def __hash__(self):
        """如果对象object为哈希表类型,返回对象object的哈希值。哈希值为整数。在字典查找中,哈希值用于快速比较字典的键。两个数值如果相等,则哈希值也相等。"""
        """ x.__hash__() <==> hash(x) """
        pass
    
        def __hex__(self):
        """ 返回当前数的 十六进制 表示 """
        """ x.__hex__() <==> hex(x) """
        pass
    
        def __index__(self):
        """ 用于切片,数字无意义 """
        """ x[y:z] <==> x[y.__index__():z.__index__()] """
        pass
    
        def __init__(self, x, base=10): # known special case of int.__init__
        """ 构造方法,执行 x = 123 或 x = int(10) 时,自动调用,暂时忽略 """
        """
        int(x=0) -> int or long
        int(x, base=10) -> int or long
    
        Convert a number or string to an integer, or return 0 if no arguments
        are given.  If x is floating point, the conversion truncates towards zero.
        If x is outside the integer range, the function returns a long instead.
    
        If x is not a number or if base is given, then x must be a string or
        Unicode object representing an integer literal in the given base.  The
        literal can be preceded by ‘+‘ or ‘-‘ and be surrounded by whitespace.
        The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to
        interpret the base from the string as an integer literal.
        >>> int(‘0b100‘, base=0)
        # (copied from class doc)
        """
        pass
    
        def __int__(self):
        """ 转换为整数 """
        """ x.__int__() <==> int(x) """
        pass
    
        def __invert__(self):
        """ x.__invert__() <==> ~x """
        pass
    
        def __long__(self):
        """ 转换为长整数 """
        """ x.__long__() <==> long(x) """
        pass
    
        def __lshift__(self, y):
        """ x.__lshift__(y) <==> x< x%y """
        """ 取余"""
        pass
    
        def __mul__(self, y):
        """ x.__mul__(y) <==> x*y """
        """ 乘"""
        pass
    
        def __neg__(self):
        """ x.__neg__() <==> -x """
        """ 相反数"""
        pass
    
        @staticmethod # known case of __new__
        def __new__(S, *more):
        """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
        pass
    
        def __nonzero__(self):
        """ x.__nonzero__() <==> x != 0 """
        """ 不存在 python3."""
        pass
    
        def __oct__(self):
        """ 返回改值的 八进制 表示 """
        """ x.__oct__() <==> oct(x) """
        pass
    
        def __or__(self, y):
        """ x.__or__(y) <==> x|y """
        """ 或"""
        pass
    
        def __pos__(self):
        """ x.__pos__() <==> +x """
        pass
    
        def __pow__(self, y, z=None):
        """ 幂,次方 """
        """ x.__pow__(y[, z]) <==> pow(x, y[, z]) """
        pass
    
        def __radd__(self, y):
        """ x.__radd__(y) <==> y+x """
        pass
    
        def __rand__(self, y):
        """ x.__rand__(y) <==> y&x """
        pass
    
        def __rdivmod__(self, y):
        """ x.__rdivmod__(y) <==> divmod(y, x) """
        pass
    
        def __rdiv__(self, y):
        """ x.__rdiv__(y) <==> y/x """
        pass
    
        def __repr__(self):
        """转化为解释器可读取的形式 """
        """ x.__repr__() <==> repr(x) """
        pass
    
        def __str__(self):
        """转换为人阅读的形式,如果没有适于人阅读的解释形式的话,则返回解释器课阅读的形式"""
        """ x.__str__() <==> str(x) """
        pass
    
        def __rfloordiv__(self, y):
        """ x.__rfloordiv__(y) <==> y//x """
        pass
    
        def __rlshift__(self, y):
        """ x.__rlshift__(y) <==> y< y%x """
        pass
    
        def __rmul__(self, y):
        """ x.__rmul__(y) <==> y*x """
        pass
    
        def __ror__(self, y):
        """ x.__ror__(y) <==> y|x """
        pass
    
        def __rpow__(self, x, z=None):
        """ y.__rpow__(x[, z]) <==> pow(x, y[, z]) """
        pass
    
        def __rrshift__(self, y):
        """ x.__rrshift__(y) <==> y>>x """
        pass
    
        def __rshift__(self, y):
        """ x.__rshift__(y) <==> x>>y """
        pass
    
        def __rsub__(self, y):
        """ x.__rsub__(y) <==> y-x """
        pass
    
        def __rtruediv__(self, y):
        """ x.__rtruediv__(y) <==> y/x """
        pass
    
        def __rxor__(self, y):
        """ x.__rxor__(y) <==> y^x """
        pass
    
        def __sub__(self, y):
        """ x.__sub__(y) <==> x-y """
        pass
    
        def __truediv__(self, y):
        """ x.__truediv__(y) <==> x/y """
        pass
    
        def __trunc__(self, *args, **kwargs):
        """ 返回数值被截取为整形的值,在整形中无意义 """
        pass
    
        def __xor__(self, y):
        """ x.__xor__(y) <==> x^y """
        pass
    
        denominator = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
        """ 分母 = 1 """
        """the denominator of a rational number in lowest terms"""
    
        imag = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
        """ 虚数,无意义 """
        """the imaginary part of a complex number"""
    
        numerator = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
        """ 分子 = 数字大小 """
        """the numerator of a rational number in lowest terms"""
    
        real = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
        """ 实属,无意义 """
        """the real part of a complex number"""
    

字符串


a = str("123")
print(a, type(a))# 123 <class 'str'>

name="Yangchangjie"


>>> var1 = "hello world"
>>> var2 = "yangchangjie"
>>> var1[0]
'h'
>>> var2[1:5]
'angc'
>>>

列表

切片等操作

names = ["Tom", "Jacks","Ycj"]
a = list()
a.append("name")

>>> s = "spam"
>>> s[0]
's'
>>> s[-1]
'm'
>>> s[-2]
'a'
>>> s[1]
'p'
>>>
>>> s[len(s)-1]
'm'
>>> s
'spam'
>>> s[1:3]
'pa'
>>> s[1:]
'pam'
>>> s[:3]
'spa'
>>> s[:-1]
'spa'
>>> s[:]
'spam'
>>>
>>> s + "xyz"
'spamxyz'
>>> s
'spam'
>>> s * 8
'spamspamspamspamspamspamspamspam'
>>> s[0]='z' # 不可变性
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> s = 'z' + s[1:]
>>> s
'zpam'
>>>

>>> s
'zpam'
>>> s.replace("pa", "xyz")
'zxyzm'
>>> s
'zpam'
>>>
>>> line = "aaa, bbb, cccc, dd"
>>> line.split(",")
['aaa', ' bbb', ' cccc', ' dd']
>>> s
'zpam'
>>> s.upper()
'ZPAM'
>>> s.isalpha()
True
>>> line = "aaa, bbb, cccc, dd\n"
>>> line = line.rstrip()
>>> line
'aaa, bbb, cccc, dd'
>>>

基本操作

L = ["a", 123, "spam", 12.345]
a = len(L)  # 4
print(L + [4, 56])  # ['a', 123, 'spam', 12.345, 4, 56]
print(L)  # ['a', 123, 'spam', 12.345] 原来的操作列表没有任何的变化
L.append("A")  # 在列表中在末尾中添加一个字符"A" ['a', 123, 'spam', 12.345, 'A']
L.pop()   # 在删除列表的尾部元素 ['a', 123, 'spam', 12.345]

M = ["bb", "aa", "cc"]
M.sort()  # ['aa', 'bb', 'cc'] 升序进行排序 对列表有改变
M.reverse()  # ['cc', 'bb', 'aa'] 进行翻转

M = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]
     ]

print(M[1])  # [4, 5, 6]
print(M[1][1])  # 5

# 列表解析
M = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]
     ]


col = [row[0] for row in M]
print(col)  # [1, 4, 7]
col1 = [row[0] + 1 for row in M]
print(col1)  # [2, 5, 8]

col1 = [(row[0]+1) for row in M if (row[0]+1) % 2 == 0]
print(col1)   # [2, 8]偶数 奇数【col1 = [(row[0]+1) for row in M if (row[0]) % 2 == 0]】 5

diag = [M[i][i] for i in [0, 1, 2]]
print(diag)  # [1, 5, 9] 斜对角

doubles = [x * 2 for x in "spam"]
print(doubles)  # ['ss', 'pp', 'aa', 'mm']
G = (sum(row) for row in M)  # ()中会创建一个迭代器 用next来访问数据
print(next(G))  # 6
print(next(G))  # 15
print(next(G))  # 24
# 类似的map的操作
list(map(sum, M))  # [6, 15, 24]
'''
map(func, *iterables) --> map object
    
    Make an iterator that computes the function using arguments from
    each of the iterables.  Stops when the shortest iterable is exhausted.
    创建一个迭代器,该迭代器使用来自的参数计算函数
    每个迭代。当最短的迭代耗尽时停止   
'''
# 解析语法创建集合和字典

{sum(row) for row in M}  # {24, 6, 15}
dict_ = {i: M[i] for i in range(len(M))}  # {0: [1, 2, 3], 1: [4, 5, 6], 2: [7, 8, 9]}

{ord(row)for row in "SPAM"}  # {80, 65, 83, 77}
dict_ = {row: ord(row) for row in "SPAM"}  # {'S': 83, 'P': 80, 'A': 65, 'M': 77}
list

                    class list(object):
            """
            list() -> new empty list
            list(iterable) -> new list initialized from iterable‘s items
            """
            def append(self, p_object): # real signature unknown; restored from __doc__
                """ L.append(object) -- append object to end """
                pass
    
            def count(self, value): # real signature unknown; restored from __doc__
                """ L.count(value) -> integer -- return number of occurrences of value """
                return 0
    
            def extend(self, iterable): # real signature unknown; restored from __doc__
                """ L.extend(iterable) -- extend list by appending elements from the iterable """
                pass
    
            def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__
                """
                L.index(value, [start, [stop]]) -> integer -- return first index of value.
                Raises ValueError if the value is not present.
                """
                return 0
    
            def insert(self, index, p_object): # real signature unknown; restored from __doc__
                """ L.insert(index, object) -- insert object before index """
                pass
    
            def pop(self, index=None): # real signature unknown; restored from __doc__
                """
                L.pop([index]) -> item -- remove and return item at index (default last).
                Raises IndexError if list is empty or index is out of range.
                """
                pass
    
            def remove(self, value): # real signature unknown; restored from __doc__
                """
                L.remove(value) -- remove first occurrence of value.
                Raises ValueError if the value is not present.
                """
                pass
    
            def reverse(self): # real signature unknown; restored from __doc__
                """ L.reverse() -- reverse *IN PLACE* """
                pass
    
            def sort(self, cmp=None, key=None, reverse=False): # real signature unknown; restored from __doc__
                """
                L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
                cmp(x, y) -> -1, 0, 1
                """
                pass
    
            def __add__(self, y): # real signature unknown; restored from __doc__
                """ x.__add__(y) <==> x+y """
                pass
    
            def __contains__(self, y): # real signature unknown; restored from __doc__
                """ x.__contains__(y) <==> y in x """
                pass
    
            def __delitem__(self, y): # real signature unknown; restored from __doc__
                """ x.__delitem__(y) <==> del x[y] """
                pass
    
            def __delslice__(self, i, j): # real signature unknown; restored from __doc__
                """
                x.__delslice__(i, j) <==> del x[i:j]
    
                           Use of negative indices is not supported.
                """
                pass
    
            def __eq__(self, y): # real signature unknown; restored from __doc__
                """ x.__eq__(y) <==> x==y """
                pass
    
            def __getattribute__(self, name): # real signature unknown; restored from __doc__
                """ x.__getattribute__(‘name‘) <==> x.name """
                pass
    
            def __getitem__(self, y): # real signature unknown; restored from __doc__
                """ x.__getitem__(y) <==> x[y] """
                pass
    
            def __getslice__(self, i, j): # real signature unknown; restored from __doc__
                """
                x.__getslice__(i, j) <==> x[i:j]
    
                           Use of negative indices is not supported.
                """
                pass
    
            def __ge__(self, y): # real signature unknown; restored from __doc__
                """ x.__ge__(y) <==> x>=y """
                pass
    
            def __gt__(self, y): # real signature unknown; restored from __doc__
                """ x.__gt__(y) <==> x>y """
                pass
    
            def __iadd__(self, y): # real signature unknown; restored from __doc__
                """ x.__iadd__(y) <==> x+=y """
                pass
    
            def __imul__(self, y): # real signature unknown; restored from __doc__
                """ x.__imul__(y) <==> x*=y """
                pass
    
            def __init__(self, seq=()): # known special case of list.__init__
                """
                list() -> new empty list
                list(iterable) -> new list initialized from iterable‘s items
                # (copied from class doc)
                """
                pass
    
            def __iter__(self): # real signature unknown; restored from __doc__
                """ x.__iter__() <==> iter(x) """
                pass
    
            def __len__(self): # real signature unknown; restored from __doc__
                """ x.__len__() <==> len(x) """
                pass
    
            def __le__(self, y): # real signature unknown; restored from __doc__
                """ x.__le__(y) <==> x<=y """
                pass
    
            def __lt__(self, y): # real signature unknown; restored from __doc__
                """ x.__lt__(y) <==> x x*n """
                pass
    
            @staticmethod # known case of __new__
            def __new__(S, *more): # real signature unknown; restored from __doc__
                """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
                pass
    
            def __ne__(self, y): # real signature unknown; restored from __doc__
                """ x.__ne__(y) <==> x!=y """
                pass
    
            def __repr__(self): # real signature unknown; restored from __doc__
                """ x.__repr__() <==> repr(x) """
                pass
    
            def __reversed__(self): # real signature unknown; restored from __doc__
                """ L.__reversed__() -- return a reverse iterator over the list """
                pass
    
            def __rmul__(self, n): # real signature unknown; restored from __doc__
                """ x.__rmul__(n) <==> n*x """
                pass
    
            def __setitem__(self, i, y): # real signature unknown; restored from __doc__
                """ x.__setitem__(i, y) <==> x[i]=y """
                pass
    
            def __setslice__(self, i, j, y): # real signature unknown; restored from __doc__
                """
                x.__setslice__(i, j, y) <==> x[i:j]=y
    
                           Use  of negative indices is not supported.
                """
                pass
    
            def __sizeof__(self): # real signature unknown; restored from __doc__
                """ L.__sizeof__() -- size of L in memory, in bytes """
                pass
    
            __hash__ = None


        

bool值

布尔值 只有True 和 False
真 1 True。
假 0 False。

>>> bool(42)
True
>>> bool()
False
>>>
bool

                    class bool(int):
            """
            bool(x) -> bool
    
            Returns True when the argument x is true, False otherwise.
            The builtins True and False are the only two instances of the class bool.
            The class bool is a subclass of the class int, and cannot be subclassed.
            """
            def __and__(self, *args, **kwargs): # real signature unknown
                """ Return self&value. """
                pass
    
            def __init__(self, x): # real signature unknown; restored from __doc__
                pass
    
            @staticmethod # known case of __new__
            def __new__(*args, **kwargs): # real signature unknown
                """ Create and return a new object.  See help(type) for accurate signature. """
                pass
    
            def __or__(self, *args, **kwargs): # real signature unknown
                """ Return self|value. """
                pass
    
            def __rand__(self, *args, **kwargs): # real signature unknown
                """ Return value&self. """
                pass
    
            def __repr__(self, *args, **kwargs): # real signature unknown
                """ Return repr(self). """
                pass
    
            def __ror__(self, *args, **kwargs): # real signature unknown
                """ Return value|self. """
                pass
    
            def __rxor__(self, *args, **kwargs): # real signature unknown
                """ Return value^self. """
                pass
    
            def __str__(self, *args, **kwargs): # real signature unknown
                """ Return str(self). """
                pass
    
            def __xor__(self, *args, **kwargs): # real signature unknown
                """ Return self^value. """
                pass
    
        

字典

创建
d = {key1 : value1, key2 : value2 }

person = {"name": "Ycj", ‘age‘: 18}

person = dict({"name": "Ycj", ‘age‘: 18})
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组

# dict
d = {"a": "b", "b": "c"}
print(d["a"])  # b
d["a"] = d["a"] + "ddd"
print(d["a"])  # bddd

d = {}  # 创建字典1
d_ = dict()  # 创建字典1
d_["name"] = "A"  # 添加元素
d_["age"] = 12
print(d_)  # {'name': 'A', 'age': 12}
d[123] = 4556
print(d)

rec = {"name": {"first_name": "Bob", "last_name": "Smith"},
       "age": {"first_age": 1, "last_age": 2},
       # "work": {"first_work": "programmer", "last_work": "farmer"},
       "job":["dev", "mgr"]
       }
print(rec["name"])  # {'first_name': 'Bob', 'last_name': 'Smith'}

rec["job"].append("janiter")
print(rec["job"])  # ['dev', 'mgr', 'janiter']

d = {chr(i): i for i in range(79, 85)}  # {'O': 79, 'P': 80, 'Q': 81, 'R': 82, 'S': 83, 'T': 84}
ks = list(d.keys())  # ['O', 'P', 'Q', 'R', 'S', 'T']
for key in list(d.keys()):

     print(key, "->", d[key])

for c in "ABC":
     # print(c.upper())  # 转换为大写 A B C
     print(c.lower())

# x = 4
# while x > 0:
#      print("spam" * x)
#      x-=1
x = 1
while x <= 4:
     print("spam" * x)
     x += 1

squares = [x ** 2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

li_data = list()

for i in range(10):
     li_data.append(i ** 3)
print(li_data)  # [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

d = {chr(i): i for i in range(79, 85)}  # {'O': 79, 'P': 80, 'Q': 81, 'R': 82, 'S': 83, 'T': 84}

d["add_data"] = "data"  # {'O': 79, 'P': 80, 'Q': 81, 'R': 82, 'S': 83, 'T': 84, 'add_data': 'data'}

print("add_data" in d)  # True
print("add_data" not in d)  # False
dict
                    class dict(object):
            """
            dict() -> new empty dictionary
            dict(mapping) -> new dictionary initialized from a mapping object‘s
                (key, value) pairs
            dict(iterable) -> new dictionary initialized as if via:
                d = {}
                for k, v in iterable:
                    d[k] = v
            dict(**kwargs) -> new dictionary initialized with the name=value pairs
                in the keyword argument list.  For example:  dict(one=1, two=2)
            """

            def clear(self): # real signature unknown; restored from __doc__
                """ 清除内容 """
                """ D.clear() -> None.  Remove all items from D. """
                pass
    
            def copy(self): # real signature unknown; restored from __doc__
                """ 浅拷贝 """
                """ D.copy() -> a shallow copy of D """
                pass
    
            @staticmethod # known case
            def fromkeys(S, v=None): # real signature unknown; restored from __doc__
                """
                dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
                v defaults to None.
                """
                pass
    
            def get(self, k, d=None): # real signature unknown; restored from __doc__
                """ 根据key获取值,d是默认值 """
                """ D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None. """
                pass
    
            def has_key(self, k): # real signature unknown; restored from __doc__
                """ 是否有key """
                """ D.has_key(k) -> True if D has a key k, else False """
                return False
    
            def items(self): # real signature unknown; restored from __doc__
                """ 所有项的列表形式 """
                """ D.items() -> list of D‘s (key, value) pairs, as 2-tuples """
                return []
    
            def iteritems(self): # real signature unknown; restored from __doc__
                """ 项可迭代 """
                """ D.iteritems() -> an iterator over the (key, value) items of D """
                pass
    
            def iterkeys(self): # real signature unknown; restored from __doc__
                """ key可迭代 """
                """ D.iterkeys() -> an iterator over the keys of D """
                pass
    
            def itervalues(self): # real signature unknown; restored from __doc__
                """ value可迭代 """
                """ D.itervalues() -> an iterator over the values of D """
                pass
    
            def keys(self): # real signature unknown; restored from __doc__
                """ 所有的key列表 """
                """ D.keys() -> list of D‘s keys """
                return []
    
            def pop(self, k, d=None): # real signature unknown; restored from __doc__
                """ 获取并在字典中移除 """
                """
                D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
                If key is not found, d is returned if given, otherwise KeyError is raised
                """
                pass
    
            def popitem(self): # real signature unknown; restored from __doc__
                """ 获取并在字典中移除 """
                """
                D.popitem() -> (k, v), remove and return some (key, value) pair as a
                2-tuple; but raise KeyError if D is empty.
                """
                pass
    
            def setdefault(self, k, d=None): # real signature unknown; restored from __doc__
                """ 如果key不存在,则创建,如果存在,则返回已存在的值且不修改 """
                """ D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D """
                pass
    
            def update(self, E=None, **F): # known special case of dict.update
                """ 更新
                    {‘name‘:‘alex‘, ‘age‘: 18000}
                    [(‘name‘,‘sbsbsb‘),]
                """
                """
                D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
                If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
                If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
                In either case, this is followed by: for k in F: D[k] = F[k]
                """
                pass
    
            def values(self): # real signature unknown; restored from __doc__
                """ 所有的值 """
                """ D.values() -> list of D‘s values """
                return []
    
            def viewitems(self): # real signature unknown; restored from __doc__
                """ 所有项,只是将内容保存至view对象中 """
                """ D.viewitems() -> a set-like object providing a view on D‘s items """
                pass
    
            def viewkeys(self): # real signature unknown; restored from __doc__
                """ D.viewkeys() -> a set-like object providing a view on D‘s keys """
                pass
    
            def viewvalues(self): # real signature unknown; restored from __doc__
                """ D.viewvalues() -> an object providing a view on D‘s values """
                pass
    
            def __cmp__(self, y): # real signature unknown; restored from __doc__
                """ x.__cmp__(y) <==> cmp(x,y) """
                pass
    
            def __contains__(self, k): # real signature unknown; restored from __doc__
                """ D.__contains__(k) -> True if D has a key k, else False """
                return False
    
            def __delitem__(self, y): # real signature unknown; restored from __doc__
                """ x.__delitem__(y) <==> del x[y] """
                pass
    
            def __eq__(self, y): # real signature unknown; restored from __doc__
                """ x.__eq__(y) <==> x==y """
                pass
    
            def __getattribute__(self, name): # real signature unknown; restored from __doc__
                """ x.__getattribute__(‘name‘) <==> x.name """
                pass
    
            def __getitem__(self, y): # real signature unknown; restored from __doc__
                """ x.__getitem__(y) <==> x[y] """
                pass
    
            def __ge__(self, y): # real signature unknown; restored from __doc__
                """ x.__ge__(y) <==> x>=y """
                pass
    
            def __gt__(self, y): # real signature unknown; restored from __doc__
                """ x.__gt__(y) <==> x>y """
                pass
    
            def __init__(self, seq=None, **kwargs): # known special case of dict.__init__
                """
                dict() -> new empty dictionary
                dict(mapping) -> new dictionary initialized from a mapping object‘s
                    (key, value) pairs
                dict(iterable) -> new dictionary initialized as if via:
                    d = {}
                    for k, v in iterable:
                        d[k] = v
                dict(**kwargs) -> new dictionary initialized with the name=value pairs
                    in the keyword argument list.  For example:  dict(one=1, two=2)
                # (copied from class doc)
                """
                pass
    
            def __iter__(self): # real signature unknown; restored from __doc__
                """ x.__iter__() <==> iter(x) """
                pass
    
            def __len__(self): # real signature unknown; restored from __doc__
                """ x.__len__() <==> len(x) """
                pass
    
            def __le__(self, y): # real signature unknown; restored from __doc__
                """ x.__le__(y) <==> x<=y """
                pass
    
            def __lt__(self, y): # real signature unknown; restored from __doc__
                """ x.__lt__(y) <==> x a new object with type S, a subtype of T """
                pass
    
            def __ne__(self, y): # real signature unknown; restored from __doc__
                """ x.__ne__(y) <==> x!=y """
                pass
    
            def __repr__(self): # real signature unknown; restored from __doc__
                """ x.__repr__() <==> repr(x) """
                pass
    
            def __setitem__(self, i, y): # real signature unknown; restored from __doc__
                """ x.__setitem__(i, y) <==> x[i]=y """
                pass
    
            def __sizeof__(self): # real signature unknown; restored from __doc__
                """ D.__sizeof__() -> size of D in memory, in bytes """
                pass
    
            __hash__ = None
    
        dict
    
        

元组

创建
ages = (11, 22, 33, 44, 55)

ages = tuple((11, 22, 33, 44, 55))

# 元组(tuple)具有不变性(不能更改)


T = (1, 2, 3, 1)

print(len(T))  # 3
print(T + (1, 4, 5, 6))  # (1, 2, 3, 1, 4, 5, 6)
print(T.count(1))  # 2 统计个数
print(T.index(3))  # 索引 返回位置 2 在元组中没有 就会报错

# 混合类的类型的嵌套

T = ("spam", 3.0, [11, 22, 33])
print(T[0])  # spam
print(T[2][2])  # 33
# tuple中没有append(x)函数
# T.append(2) Error
tuple
            lass tuple(object):
                """
                tuple() -> empty tuple
                tuple(iterable) -> tuple initialized from iterable‘s items

                If the argument is a tuple, the return value is the same object.
                """
                def count(self, value): # real signature unknown; restored from __doc__
                    """ T.count(value) -> integer -- return number of occurrences of value """
                    return 0
    
                def index(self, value, start=None, stop=None): # real signature unknown; restored from __doc__
                    """
                    T.index(value, [start, [stop]]) -> integer -- return first index of value.
                    Raises ValueError if the value is not present.
                    """
                    return 0
    
                def __add__(self, y): # real signature unknown; restored from __doc__
                    """ x.__add__(y) <==> x+y """
                    pass
    
                def __contains__(self, y): # real signature unknown; restored from __doc__
                    """ x.__contains__(y) <==> y in x """
                    pass
    
                def __eq__(self, y): # real signature unknown; restored from __doc__
                    """ x.__eq__(y) <==> x==y """
                    pass
    
                def __getattribute__(self, name): # real signature unknown; restored from __doc__
                    """ x.__getattribute__(‘name‘) <==> x.name """
                    pass
    
                def __getitem__(self, y): # real signature unknown; restored from __doc__
                    """ x.__getitem__(y) <==> x[y] """
                    pass
    
                def __getnewargs__(self, *args, **kwargs): # real signature unknown
                    pass
    
                def __getslice__(self, i, j): # real signature unknown; restored from __doc__
                    """
                    x.__getslice__(i, j) <==> x[i:j]
    
                               Use of negative indices is not supported.
                    """
                    pass
    
                def __ge__(self, y): # real signature unknown; restored from __doc__
                    """ x.__ge__(y) <==> x>=y """
                    pass
    
                def __gt__(self, y): # real signature unknown; restored from __doc__
                    """ x.__gt__(y) <==> x>y """
                    pass
    
                def __hash__(self): # real signature unknown; restored from __doc__
                    """ x.__hash__() <==> hash(x) """
                    pass
    
                def __init__(self, seq=()): # known special case of tuple.__init__
                    """
                    tuple() -> empty tuple
                    tuple(iterable) -> tuple initialized from iterable‘s items
    
                    If the argument is a tuple, the return value is the same object.
                    # (copied from class doc)
                    """
                    pass
    
                def __iter__(self): # real signature unknown; restored from __doc__
                    """ x.__iter__() <==> iter(x) """
                    pass
    
                def __len__(self): # real signature unknown; restored from __doc__
                    """ x.__len__() <==> len(x) """
                    pass
    
                def __le__(self, y): # real signature unknown; restored from __doc__
                    """ x.__le__(y) <==> x<=y """
                    pass
    
                def __lt__(self, y): # real signature unknown; restored from __doc__
                    """ x.__lt__(y) <==> x x*n """
                    pass
    
                @staticmethod # known case of __new__
                def __new__(S, *more): # real signature unknown; restored from __doc__
                    """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
                    pass
    
                def __ne__(self, y): # real signature unknown; restored from __doc__
                    """ x.__ne__(y) <==> x!=y """
                    pass
    
                def __repr__(self): # real signature unknown; restored from __doc__
                    """ x.__repr__() <==> repr(x) """
                    pass
    
                def __rmul__(self, n): # real signature unknown; restored from __doc__
                    """ x.__rmul__(n) <==> n*x """
                    pass
    
                def __sizeof__(self): # real signature unknown; restored from __doc__
                    """ T.__sizeof__() -- size of T in memory, in bytes """
                    pass
    
        

也下是python的常见的内置函数

详细见python文档,猛击这里

文件操作

文件操作

  • 打开文件
  • 操作文件

打开文件

文件句柄 = file('文件路径', '模式')

python中打开文件有两种方式,即:open(...) 和 file(...) ,本质上前者在内部会调用后者来进行文件操作,推荐使用 open()

打开文件的模式有:

r,只读模式(默认)。
w,只写模式。【不可读;不存在则创建;存在则删除内容;】
a,追加模式。【可读; 不存在则创建;存在则只追加内容;】

"+" 表示可以同时读写某个文件

r+,可读写文件。【可读;可写;可追加】
w+,写读
a+,同a
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)

rU
r+U
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)

rb
wb
ab
文件的常用的操作方法:
read(3):

  1. 文件打开方式为文本模式时,代表读取3个字符。

  2. 文件打开方式为b模式时,代表读取3个字节。

其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate。

注意:

  1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的。

  2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果。

基本操作

# # 写模式 w  会把原先的内容清空 在写入
# f = open('log.txt', mode="w", encoding="utf-8")  # open默认的读模式
# f.write("hello 你好!")  # 读文件
# f.close()

# 写模式 wb 二进制文件  会把原先的内容清空 在写入
#
# f = open('log.txt', mode='wb')  # 就不需要encoding(编码)
# f.write("This is test".encode("utf-8"))  # 编码成utf-8
# f.close()

# # 读 r模式
# f = open("log.txt", mode='r', encoding="utf-8")
# print(f.read())  # hello 你好!
# f.close()
#
# 读 rb模式
# f = open("log.txt", mode='rb')
# # print(f.read())  # b'This is test'
# # f.close()

# 追加 a模式 在原先的内容后面添加数据

# f = open("log.txt", mode='a', encoding='utf-8')
# f.write("中国")   # 原先的log.txt文件的内容是 This is test  现在的内容是:This is test中国
# f.close()

# 追加 ab模式 在原先的内容后面添加数据
# f = open("log.txt", mode='ab')
# f.write('我'.encode('utf-8'))  # This is test中国我
# f.close()

# # r+ 读写
# f = open('log.txt', mode='r+', encoding='utf-8')
# print(f.read()) # XXXXXXXXXXXXXXXXXX
# f.write("aaa")
# f.seek(0)
# print(f.read())  # XXXXXXXXXXXXXXXXXXaaa
# f.close()

# # w+ 写读

# f = open('log.txt', mode='w+', encoding='utf-8')
# f.write('中国')
# f.seek(0)  # 把光标移到收位置 光标是按照字节数来索引  中文是3的倍数,中文一个字占3个字节
# print(f.read()) # 中国


# 读文件

# FileRead = open("log.txt", 'r', encoding='utf-8')
# for lines in FileRead.readlines():  # readlines 全部读取保存在列表中
#     print("lines:", lines.strip('\n'))
# FileRead.close()

# FileRead = open("log.txt", 'r', encoding='utf-8')
# print(FileRead.readline().strip('\n'))  # 一行一行读取   中国
# print(FileRead.readline().strip('\n'))               # 北京
# print(FileRead.readline().strip('\n'))               # 上海
#
# FileRead.close()
# FileRead = open("log.txt", 'r', encoding='utf-8')
# print(FileRead.tell())  # tell 返回光标的位置  0
# FileRead.close()

# 
# FileRead = open("log.txt", 'a+', encoding='utf-8')   # 文件内容:abcdefghijklmn
# FileRead.truncate(4)   # 文件内容:abcd  截取了4个字符保留
# FileRead.close()

文件的修改

方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,
再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)

"""
# log.txt文件内容
中国
北京
上海
天津
"""
import os
with open('log.txt', mode='r',  encoding='utf-8') as read_f, open('log.bak', mode='w', encoding='utf-8') as write_f:
    data = read_f.read()
    data = data.replace('北京', 'beijing')
    write_f.write(data)
    

os.remove('log.txt')  # 删除原来的文件
os.rename('log.bak', 'log.txt')  # 对改过的文件,进行重新命名

"""
中国
beijing
上海
天津
"""

方式二:将硬盘存放的该文件的内容一行一行地读入内存,
修改完毕就写入新文件,最后用新文件覆盖源文件。

"""
# log.txt文件内容
中国
北京
上海
天津
"""
import os
with open('log.txt', mode='r',  encoding='utf-8') as read_f, open('log.bak', mode='w', encoding='utf-8') as write_f:
    for line in read_f:
        if '北京' in line:
            line = line.replace("北京", 'beijing')
        write_f.write(line)
        
os.remove('log.txt')  # 删除原来的文件
os.rename('log.bak', 'log.txt')  # 对改过的文件,进行重新命名
"""
中国
beijing
上海
天津
"""

test:

文件a内容:每一行内容分别为商品名字,价钱,个数。

apple 10 3

tesla 100000 1

mac 3000 2

lenovo 30000 3

chicken 10 3

通过代码,将其构建成这种数据类型:[{‘name‘:‘apple‘,‘price‘:10,‘amount‘:3},{‘name‘:‘tesla‘,‘price‘:1000000,‘amount‘:1}......] 并计算出总价钱。

def deal_file(dir_='log.txt'):
    with open(dir_, 'r', encoding='utf-8') as f:
            list_ = f.readlines()
            res_list = []
            for i in range(0, len(list_), 2):
                    res_list.append(list_[i].strip().split())

            res_tuple = []
            d = dict()
            for i in range(len(res_list)):
                d = {"name": res_list[i][0], "price": res_list[i][1], "amount": int(res_list[i][2])}

                res_tuple.append(d)

            sum = 0
            for i in res_tuple:

                sum += int(i['price']) * int(i['amount'])

            print("sum:", sum)
            print(res_tuple)


deal_file()
#________________________________
sum: 196060
[{'name': 'apple', 'price': '10', 'amount': 3}, {'name': 'tesla', 'price': '100000', 'amount': 1}, {'name': 'mac', 'price': '3000', 'amount': 2}, {'name': 'lenovo', 'price': '30000', 'amount': 3}, {'name': 'chicken', 'price': '10', 'amount': 3}]

file操作函数
            class file(object):

    def close(self): # real signature unknown; restored from __doc__
        关闭文件
        """
        close() -> None or (perhaps) an integer.  Close the file.
         
        Sets data attribute .closed to True.  A closed file cannot be used for
        further I/O operations.  close() may be called more than once without
        error.  Some kinds of file objects (for example, opened by popen())
        may return an exit status upon closing.
        """
     
    def fileno(self): # real signature unknown; restored from __doc__
        文件描述符  
         """
        fileno() -> integer "file descriptor".
         
        This is needed for lower-level file interfaces, such os.read().
        """
        return 0    
     
    def flush(self): # real signature unknown; restored from __doc__
        刷新文件内部缓冲区
        """ flush() -> None.  Flush the internal I/O buffer. """
        pass

 






    def isatty(self): # real signature unknown; restored from __doc__
        判断文件是否是同意tty设备
        """ isatty() -> true or false.  True if the file is connected to a tty device. """
        return False

    def next(self): # real signature unknown; restored from __doc__
        获取下一行数据,不存在,则报错
        """ x.next() -> the next value, or raise StopIteration """
        pass
     
    def read(self, size=None): # real signature unknown; restored from __doc__
        读取指定字节数据
        """
        read([size]) -> read at most size bytes, returned as a string.
         
        If the size argument is negative or omitted, read until EOF is reached.
        Notice that when in non-blocking mode, less data than what was requested
        may be returned, even if no size parameter was given.
        """
        pass
     
    def readinto(self): # real signature unknown; restored from __doc__
        读取到缓冲区,不要用,将被遗弃
        """ readinto() -> Undocumented.  Don‘t use this; it may go away. """
        pass
     
    def readline(self, size=None): # real signature unknown; restored from __doc__
        仅读取一行数据
        """
        readline([size]) -> next line from the file, as a string.
         
        Retain newline.  A non-negative size argument limits the maximum
        number of bytes to return (an incomplete line may be returned then).
        Return an empty string at EOF.
        """
        pass
     
    def readlines(self, size=None): # real signature unknown; restored from __doc__
        读取所有数据,并根据换行保存值列表
        """
        readlines([size]) -> list of strings, each a line from the file.
         
        Call readline() repeatedly and return a list of the lines so read.
        The optional size argument, if given, is an approximate bound on the
        total number of bytes in the lines returned.
        """
        return []
     
    def seek(self, offset, whence=None): # real signature unknown; restored from __doc__
        指定文件中指针位置
        """
        seek(offset[, whence]) -> None.  Move to new file position.
         
        Argument offset is a byte count.  Optional argument whence defaults to
        0 (offset from start of file, offset should be >= 0); other values are 1
        (move relative to current position, positive or negative), and 2 (move
        relative to end of file, usually negative, although many platforms allow
        seeking beyond the end of a file).  If the file is opened in text mode,
        only offsets returned by tell() are legal.  Use of other offsets causes
        undefined behavior.
        Note that not all file objects are seekable.
        """
        pass
     
    def tell(self): # real signature unknown; restored from __doc__
        获取当前指针位置
        """ tell() -> current file position, an integer (may be a long integer). """
        pass
     
    def truncate(self, size=None): # real signature unknown; restored from __doc__
        截断数据,仅保留指定之前数据
        """
        truncate([size]) -> None.  Truncate the file to at most size bytes.
         
        Size defaults to the current file position, as returned by tell().
        """
        pass
     
    def write(self, p_str): # real signature unknown; restored from __doc__
        写内容
        """
        write(str) -> None.  Write string str to file.
         
        Note that due to buffering, flush() or close() may be needed before
        the file on disk reflects the data written.
        """
        pass
     
    def writelines(self, sequence_of_strings): # real signature unknown; restored from __doc__
        将一个字符串列表写入文件
        """
        writelines(sequence_of_strings) -> None.  Write the strings to the file.
         
        Note that newlines are not added.  The sequence can be any iterable object
        producing strings. This is equivalent to calling write() for each string.
        """
        pass
     
    def xreadlines(self): # real signature unknown; restored from __doc__
        可用于逐行读取文件,非全部
        """
        xreadlines() -> returns self.
         
        For backward compatibility. File objects now include the performance
        optimizations previously implemented in the xreadlines module.
        """
        pass
    
    

格式化的输出(%s、format)


print("This is %s" % "test")  # This is test
print("%s , %d , %s" % ('a', 12, 'b'))  # a , 12 , b
print('3%% %s' % "abc")  # 显示%号

str_ = '''
    a b c d %s
      a b c %s
        a b %s
          a %s
            %s
    ''' % ("e", "d", "c", "b", "a")


# a b c d e
#   a b c d
#     a b c
#       a b
#         a

# format() 输出

# 位置显示
'a1 ={}, a2={}, a3={}'.format("1", "2", "3")     # a1 =1, a2=2, a3=3
'a1 ={1}, a2={2}, a3={0}'.format("1", "2", "3")     # a1 =2, a2=3, a3=1

"Your name is{name}, age is {age}".format(name="A", age=12)  # Your name isA, age is 12
"Your name is{name}, age is {age}".format(age=12, name="A")  # Your name isA, age is 12 和位置无关
# 对象的的属性

class A:
    def __init__(self, name, age):  # 构造函数
        self.name = name
        self.age = age


        P = A("B", 18)
        "name is: {p.name}, age is:{p.age}".format(p=P) # name is: B, age is:18

# 通过下标
s1 = [1, "23", "S"]
s2 = ["s2.1", "s2.2", "s2.3"]

'{0[1]}  {0[2]} {1[2]} {1[0]}'.format(s2, s1)  # s2.2  s2.3 S 1

# 格式化输出

a = '[{:<10}]'.format('12')  # 默认填充空格的  输出左对齐定长为10位 [12        ]
b = "[{:>10}]".format("abc")  # 默认填充空格的  输出左对齐定长为10位 [       abc]
c = "[{:*>10}]".format("abc")  # 输出左对齐定长为10位 填入一个ascii字符  [*******abc]
d = "[{:*<10}]".format("abc")  # 输出右对齐定长为10位 填入一个ascii字符  [abc*******]
e = "[{:*^10}]".format("abc")  # 输出居中对其为10位 填入一个ascii字符  [***abc****]


# 浮点小数输出
import math
a1 = "{:.6f}".format(math.pi) # 3.141593     通常都是配合 f 使用,其中.2表示长度为2的精度,f表示float类型

a2 = "{:,}".format(12345945852326.1524512345)  # 12,345,945,852,326.152

# 进制及其他显示

    '''
b : 二进制
d :十进制
o :八进制
!s :将对象格式化转换成字符串
!a :将对象格式化转换成ASCII
!r :将对象格式化转换成repr
'''
    b1 = '{:b}'.format(10)  #二进制 :1010
    b2 = '{:d}'.format(10)  # 10进制 :10
    b3 = '{:o}'.format(45)  # 8进制 :55
    b4 = '{:x}'.format(45)  # 16进制 :2d
    b5 = '{!s}'.format('45')  # 45
    b6 = "{!a}".format("10")  # '10'
    b7 = "{!r}".format("10")  # '10'
    print(b7)

其他的类型

x = set("spam")

y = {"h", "a", "m"}

print(x & y)  # 与 {'m', 'a'}
print(x | y)  # 或 {'p', 'm', 's', 'h', 'a'}
print(x - y)  # {'p', 's'}
print(y - x)  # {'h'}

print(1/3)  # 0.3333333333333333
import decimal
d = decimal.Decimal("3.14")
d = d + 12
print(d)  # 15.14


from fractions import Fraction  # 转换为分式
f = Fraction(2, 3)  # 2/3
f = f + 1  # 5/3
f_ = f + Fraction(10, 27)
print(f_)  # 55/27

python内置函数

str(字符串)

str_ = "abc\tdefghAa"
print(str_.capitalize())  # Abcdefgh
print(str_.center(20, "_"))  # ______abcdefgh______
print(str_.count("a"))   # 2
print(str_.endswith("b"))  # 也什么结尾
print(str_.startswith("a"))  # 也什么开始
print(str_.lower())  # 全部变成小写
print(str_.upper())  # 全部变成大写
print(str_.index("a"))  # 索引 没有报错 0
print(str_.find("d"))  # 索引 没有不报错 3
print(str_.rfind("a"))
print(str_.casefold())  # abcdefgha 和lower类似
print(str_.encode())  # 回编码后的字符串 b'abcdefghAa'
print(str_.isalnum())  # True 所有字符都是字母数字,则返回 True
print(str_.expandtabs())  # abc     defghAa 遇见\t,\t前面的字符站8个字符,默认 如果没有没有8个字符,填空格
print(str_.isdecimal())  # 全部是10进制, 返回true
print(str_.isprintable())   # False 判断是否为可打印字符串
print(str_.islower())  # False 有大小写字母都是小写字母,则返回True
print(str_.isspace())  # answer: False 所有字符都是空格,则返回True
print(str_.isdigit())  # answer: False 所有字符都是数字,则返回True
print(str_.isalpha())  # answer:False 所有字符都是字母,则返回True
print(str_.isupper())  # answer:False 所有的字符是大写 ,则返回True
print(str_.istitle())  # answer:False 字符串的所有的单词的首字母,是否为大写,其他的是否小写,则返回True ,for example:"Title"
print(str_.isidentifier()) # answer:False 如果S是一个有效的标识符,返回True ;for example :"data".isindentifier() return True
str_data = ("a", "b", "c")
print("-".join(str_data))  # answer: a-b-c 序列中的元素以指定的字符连接生成一个新的字符串。
print("-".join(str_))  # answer: -d-e-f-g-h-A-a
str_ = "abc\tdefghAa"
print(str_.swapcase())  # 将大写字符转换为小写(小变大,大变小)  ABC  DEFGHaA

str_data = "abcdef"
print(str_data.zfill(10))  # 0000abcdef 填充一个左边为0的数字字符串S
str_data = "   abcfe    "
print(str_data.lstrip())  # answer:abcfe  返回去掉前导空格的字符串S的副本。如果字符是给定的而不是空字符,则删除字符中的字符。
str_ = "abc\tdefghAa"
print(str_.rsplit())  # answer:['abc', 'defghAa'] 指定分隔符对字符串进行切片,如果参数 num 有指定值
print(str_data.strip())    # 去除左右空格
print(str_data.rstrip())  # answer:   abcfe 去除右空格
print(str_.ljust(20, "*"))  # answer:abc    defghAa********* 右填充"char" len 20 以Unicode长宽度字符串返回左对齐。填充使用指定的填充字符完成(默认为空格)。
print(str_.rjust(20), "^")  # answer:          abc  defghAa ^, 返回右对齐的长度宽度字符串。填充使用指定的填充字符完成(默认为空格)。
intab = "aeiou"
outtab = "12345"
trantab = str.maketrans(intab, outtab) # 简单理解是替换
print(trantab)  # {97: 49, 101: 50, 105: 51, 111: 52, 117: 53}
str = "this is string example....wow!!!"
print (str.translate(trantab))  # th3s 3s str3ng 2x1mpl2....w4w!!!
print(str_.splitlines())  # answer:['abc\tdefghAa']   返回S中的行列表,在行边界处断开。
print(str_.replace("a", "v")) # vbc defghAv 替换a -> v
test = "abcdefgh"
print(test.partition("d"))  # 分割 ('abc', 'd', 'efgh') 搜索S中的sep分隔符,返回之前的部分
print(test.rpartition("a"))  # (head, sep, tail)->('', 'a', 'bcdefgh')
print(test.zfill(20))  # answer: 000000000000abcdefgh 返回长度为width的字符,源字符string右对齐,前面填0

dict(字典)

d = {"a": "A", "b": "B", "c": "C"}
print(list(d.keys()))  # answer: ['a', 'b', 'c']  返回键key
print(list(d.values()))  # answer: ['A', 'B', 'C'] 返回值values
# print(d.clear())    # answer: None  中删除(清除)所有项目

print(d.copy())  # 拷贝 和原数据一模一样
d_ = d.copy()
print(d_)  # {'a': 'A', 'b': 'B', 'c': 'C'}

print(d.fromkeys("A", "xx"))  # answer:{'A': 'xx'} 返回一个新的字典,其中键来自iterable,值等于值
x = ("goole", "apple", "sony")
print(d.fromkeys(x, 1))  # {'goole': 1, 'apple': 1, 'sony': 1}

print(d.get("a"))  # answer: A ; 通过key -> values 没有key 返回None
# print(d.pop("a"))  # 删除 a的键和值
print(d)  # {'b': 'B', 'c': 'C'}

print(list(d.items()))  # 返会key和values 也元组的形式出现 [('b', 'B'), ('c', 'C')]
print(d.popitem())   # 删除item 默认是从后面删除
print(d)   # {'a': 'A', 'b': 'B'}


print(d.setdefault("A"))  # D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D 如果key存在,返回key,
# 否则创建字典{key:None}创建key是你查询的key
print(d)  # {'a': 'A', 'b': 'B', 'A': None}
d = {"a": "A", "b": "B", "c": "C"}
d1 = {"xxx": "test"}
d.update(d1)  # 会对原数据进行修改 将d1的数据加入d中
print(d)  # {'a': 'A', 'b': 'B', 'c': 'C', 'xxx': 'test'}

list(列表)

list_ = [1, "a", "v", 4153.01]
print(list_.pop(0))  # 删除list_[0]元素
print(list_)  # ['a', 'v', 4153.01]
b = list_.copy()  # 拷贝  ['a', 'v', 4153.01]
print(b)

# print(list_.clear())  # 删除(清除)列表
# print(list_)  # [] 空列表
# list_ = ['a', 'v', 4153.01]
print(list_.index("v", 0, 5))  # L.index(value, [start, [stop]]) -> integer -- return first index of value.
# 返回第一个索引值  answer: 1

print(list_.count("x"))  # count统计个数 answer: 0
print(list_.append("x"))  # 在list尾部添加元素
print(list_)  # ['a', 'v', 4153.01, 'x']
list_.reverse()  # 反转(前后替换)
print(list_)

# list.sort(cmp=None, key=None, reverse=False) reverse -- 排序规则,reverse = True 降序, reverse = False 升序(默认)
test = ["google", "facebook", "123"]
t = [1, 99, 12, 45]
t.sort(reverse=True)  # [99, 45, 12, 1] 降序
test.sort(reverse=False)  # 升序 ['123', 'facebook', 'google']
print(test)
print(t)

list_= ['x', 4153.01, 'v', 'a']
list_.remove("a")
print(list_)  # 移除 ['x', 4153.01, 'v']

# extend() 函数用于在列表末尾一次性追加另一个序列中的多个值
list_.extend(["u", "f"])  # L.extend(iterable) -> None -- extend list by appending elements from the iterable
print(list_)  # ['x', 4153.01, 'v', 'u', 'f']
list_.insert(1, "name")  # 插入 在第一个位置插入"name" ['x', 'name', 4153.01, 'v', 'u', 'f']

tuple(元组)

tuple_ = (1, 2, 3, 1)

print(tuple_.count(1))  # 2
print(tuple_.index(1, 0, 4))  # 0


set_ = {2, 45, 6, 789, 45}
set_.add("ADD_Functions")  # 随机添加 {2, 6, 45, 789, 'ADD_Functions'}
print(set_)
set_.remove(2)  # 移除  如果移除的元素不在集合中将发生错误
print(set_)   # {'ADD_Functions', 6, 45, 789}

# set_.clear()  # 集合中删除所有元素
print(set_)  # set()

print(set_.copy())  # 拷贝{'ADD_Functions', 789, 45, 6}
set_1 = {12, 789}
set_.update(set_1)
print(set_)  # {'ADD_Functions', 6, 12, 45, 789}

set_1 = {12, 789}
set_ = {45, 6, 'ADD_Functions'}
print(str_)
print(set_.difference(set_1))  # 差集 {45, 6, 'ADD_Functions'}


set_1 = {6, 789}
set_ = {45, 6, 'ADD_Functions'}
set_.difference_update(set_1)  # 移除两个集合中都存在的元素。
print(set_)  # {'ADD_Functions', 45}

set_1 = {6, 789}
set_ = {45, 6, 'ADD_Functions'}

set_.symmetric_difference_update(set_1)  # 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中

print(set_)  # {789, 'ADD_Functions', 45} 相同的元素6删除 将789添加到set_中


set_1 = {6, 789}
set_ = {45, 6, 'ADD_Functions'}

set_.union(set_1)

print(set_)

# 交集(&)  (intersection)
set_1 = {6, 789}
set_ = {45, 6, 'ADD_Functions'}
print(set_.intersection(set_1))  # {6}
# difference - 差集
print(set_.difference(set_1))  # {'ADD_Functions', 45}
# union 或|
print(set_.union(set_1))  # {789, 6, 'ADD_Functions', 45}

# 对称差集(^)
print(set_.symmetric_difference(set_1))  # {45, 789, 'ADD_Functions'} 除去相同的元素的集合

# set.issubset(x)  判断一个集合是否是另一个集合的子集

print(set_.issubset(set_1))  # False

# set.isuperset(x)  判断一个集合是否是另一个集合的父集

print(set_.issuperset({6}))  # True

# symmetric_difference_update() 对称更新差集

# 将s2更新到s1中的同时去除s2 和s1中相同的元素
s1 = {'ljl', 'wc', ' xy', 'zb', 'lsy'}
s2 = {'mmf', 'lsy', 'syj'}
s1.symmetric_difference_update(s2)
print(s1)  # {'ljl', 'zb', 'mmf', ' xy', 'syj', 'wc'}

# isjoint() 检测2个集合是否不存在交集 存在交集 False
s1 = {'ljl', 'wc',' xy', 'zb', 'lsy'}
s2 = {'mmf','lsy','syj'}
s3 = {1, 2}
print(s1.isdisjoint(s2))  # False
print(s1.isdisjoint(s3))  # True

# intersection_update 交集更新操作
s1 = {'ljl', 'wc', 'xy', 'zb', 'lsy'}
s2 = {'mmf', 'lsy', 'syj'}
s1.intersection_update(s2)
s2.intersection_update(s1)
print(s1)  # {'lsy'}
print(s2)  # {'lsy'}

s = frozenset('a',)  # 不可变的集合

set_1 = {6, 789}
set_ = {45, 6, 'ADD_Functions'}
set_.discard(6)  # 如果元素是成员,则从集合中删除元素。如果元素不是成员,则什么也不做。
print(set_)  # {'ADD_Functions', 45}
set_.discard(87)
print(set_)  # {'ADD_Functions', 45}

print(set_.isdisjoint(set_1))  # answer:True 如果两个集合有null交集,返回True

动态类型

变量、对象和引用

在 c、c++、java在定义变量,要声明变量的类型。例如 int a = 123;但是在python中输入a=3时候,
python怎么样知道那是一个整数?怎么样知道a是什么?

1.创建变量:当代码第一次赋值给一个变量时就创建了这个变量,在之后的赋值过程关联值,python在代码运行之前先检验变量名,可以当成是最初的赋值创建变量。

2.变量声明:python中类型只存在于对象中,而不是变量,变量是通用的,他只是在程序的某一段时间引用了某种类型的对象而已,比如定义a =1 ,a = ‘a‘,一开始定义了变量a为指向了整型的对象,然后变量又指向了字符串类型的变量,可见,变量是不固定的类型。

3.变量使用:变量出现在表达式中就会马上被对象所取代,无论对象是什么内类型,变量在使用前必须要先定义。

值得注意的是,变量必须在初始化名字之后才能更新他们,比如计数器初始化为0,然后才能增加他。

在python的赋值语句中,python做了下面的三个操作

  1. 创建一个对象代表值3。
  2. 创建一个变量a,如果它还没有创建的话。
  3. 将变量和新的对象3进行连接。

在python中,变量和对象保存在内存的不同的部分,并通过连接相关联,变量总是连接对象,并且
绝不会连接到其他变量上,但是更大的对象可能连接其他的对象(列表能够连接到它所包含的对象)。

技术分享图片

python中变量到对象的连接称为引用,引用是一种关系,也内存中的指针形式实现,一旦变量被使用了,python就会自动跟随这个变量对象连接。术语上来说:

  • 变量是一个系统表的元素,拥有指向对象的连接的空间。
  • 对象是分配的一块内存,有足够的空间去表示他们所代表的值。
  • 引用是自动形成的的变量到对象的指针。

对象的垃圾回收-

每个对象都有两个标准头部信息,一个是类型标志符,用于标记对象类型,另一个是引用计数器,用来决定是不是可回收对象。很显然,在python中只有对象才有类别区分,变量不过是引用了对象,变量并不具有类别区分,他只是在特定时间引用某个特定对象。

对于引用计数器的使用,则关联到python的垃圾回收机制,当当一个变量名赋予了一个新的对象,那么之前旧的对象占用的地址空间就会被回收。旧对象的空间自动放入内存空间池,等待后来的对象使用。

计数器在垃圾回收的过程中有事如何工作的呢?计数器记录的是当前指向对象的引用数目,如果在某时刻计数器设置为0,则表示未被引用,name这个对象的内存空间就会收回。

对象的垃圾回收有着很大的意义,这使得我们在python中任意使用对象而且不需要考虑释放空间。

类型属于对象,而不是变量,在对象的垃圾收集中,每当一个变量名被赋予了一个新的对象,之前的那个对象占用的空间将被回收(如果没有被其他的变量名或对对象所引用的话),这种自动回收对象的空间的技术叫垃圾收集。

共享引用

当单个变量被赋值引用了多个对象的情况。例如下面的情况:

a = 3
b = a

技术分享图片

a =
b = a
a = "a"

技术分享图片
共享变量

技术分享图片

也上面图可以了解到,每个数组存了一个4个字节的数字,数组开辟了4*4个字节的连续的存储空间,所以数组要求单一数据类型,否则长度不可控,无法索引。这里对数组进行索引就直接拿到某段内存里面存取的数据。

可以通过存储区的起始地址Loc (e0)加上逻辑地址(第i个元素)与存储单元大小(c)的乘积计算而得,即:
Loc(ei) = Loc(e0) + c*i
访问指定元素时无需从头遍历,通过计算便可获得对应地址,其时间复杂度为O(1)。

列表作为python的数据类型,显然不能像数组一样存取数据,如果直接讲列表存储的数据放到内存空间,那么我们就无法直接索引了,python列表的做法于数组极为相似,只是他存储的时候使用的是存储数据的内存地址,这个内存地址大小是固定的,根据内存地址找到相应的地址存储的数据,所以列表不是一段连续的数据类型(如果列表中的数据类型一致,存在连续的内存空间是更好的选择)

深浅拷贝就是拷贝列表的内存地址还是包括内存地址指向的数据一同拷贝

两个对象同时指向了一个列表的内存地址,而列表又映射了里面各元素的内存地址,变量的共享并不关注列表的改变,他们只关心列表的内存空间是否改变,所以,可变对象在引用时自身可以改变,所以不需要创建新的对象,所以共享对象会随之前对象的变化而变化。我们可以使用拷贝对象创建引用,这种方法并不适用于不可索引但是可变的字典与集合,所以python的copy模块用于变量引用:

a=[1,2,3]
b=a[:]
a.append(4)
print(a)
print(b)

result:
[1, 2, 3, 4]
[1, 2, 3]

import copy
a=[1,2,3,[1,2]]
b=copy.copy(a) # 这种拷贝方式与[:]是同样的效果
c=copy.deepcopy(a)
d=a
a.append(4)
a[3][0]=5
print(a)
print(b)
print(c)
print(d)
result:
[1, 2, 3, [5, 2], 4]
[1, 2, 3, [5, 2]]
[1, 2, 3, [1, 2]]
[1, 2, 3, [5, 2], 4]

在python中,任何东西都是在赋值与引用中工作的,对于理解python动态类型,在以后的工作与学习时是有很大帮助的,这是python唯一的赋值模型,所以准确的理解与应用十分有必要。不对类型作约束,这使得python代码极为灵活高效,并且省去了大量的代码,极为简洁,所以python是这样一门有艺术的编程。
赋值

技术分享图片

浅拷贝

浅拷贝,在内存中只额外创建第一层数据

 n1 = {"k1": "Yang", "k2": 456, "k3": ["name",789]}
 n3 = copy.copy(n1)

技术分享图片

深拷贝

深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化)

 n1 = {"k1": "Yang", "k2": 456, "k3": ["name",789]}
 n3 = copy.deepcopy(n1)

技术分享图片

if测试和语法规则

python的if语句是选取要执行的操作,这是python中主要的选择工具,if语句就可以包含其他的语句,包括其他的if在内,可以实现任意的扩展嵌套。

通用的格式

if<test1>:
    <statement1>
esif<test2>:
    <statement2>
else:
    <statement3>

例子:

if not 1:
    print(True)
else:
    print(False)

if 1:
    print(True)

# 多路分支

name = "Ycj"
if name == "Ycj":
    print("name is Ycj")
elif name == "Tom":
    print("name is Tom")
else:
    print("other people")

真值测试

  • 任何非零数字或非空对象都为真。
  • 数字零、空对象以及特殊对象None都会认为是假。
  • 计较和相等的测试会递归地运用到数据结构中。
  • 比较和相等的测试会返回True或False(1和0的特殊版本)
x and y 
    如果x和y都位真,就是真
x or y
    如果x或y都位真,就是真
not x
    如果x为假,那么就是真(表达式返回True 或Fasle)

测试

>>> 2 or 3 , 3 or 2 # 返回左侧的对象
(2, 3)
>>> 2 < 3 , 3 < 2
(True, False)
>>> [] or 3
3
>>> [] or {}
{}
>>> 2 and 3, 3 and 2 # 返回右侧的对象
(3, 2) 
>>> [] and {}
[]
>>> 3 and {}
{}

if/else三元表达式

if x:   
    A = y
else:
    A = z

上面的代码可以通过一个表达式的形式来表示,达到相同的结果

A = y if x else z

测试:

A = 't' if "spam " else 'a'
B = 'c' if '' else 'd'
print(A)  # t
print(B)  # d

a = ["f", "t"][bool("")]
b = ["f", "t"][bool("spam")]
print(a)  # f
print(b)  # t

while和for循环

while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为

while 判断条件:
    执行语句……

例子:

i = 5
while i> 0:
    print(i)
    i-=1

while 语句时还有另外两个重要的命令 continue,break 来跳过循环,continue 用于跳过该次循环,break 则是用于退出循环,此外"判断条件"还可以是个常值,表示循环必定成立。


i = 1
while i < 5:
    i += 1
    if i % 2 > 0:
        continue  # 跳出该次的循环
    print(i)


i = 1
while 1:  
    print(i)

    i += 1
    if i > 5:
        break  # 退出循环

while … else 在循环条件为 false 时执行 else

y =13
x = y // 2
while x > 1:
    if y % x == 0:
        print(y, "has factor", x)
        break
    x -= 1

else:
    print(y, "is prime")

answer: 13 is prime

for循环

for循环可以遍历任何序列的项目,如一个列表或者一个字符串。

表达式

for iterating_var in sequence:
   statements(s)

# 一般的形式
for <target> in <object>:
    <statements>
else:
    <statements>

基本的应用


for i in ["a", "b", "c"]:
    print(i,end=" ")  # a b c 

sum = 0
for i in [1, 2, 3, 4]:
    sum += i
print(sum)

prod = 1
for item in [1, 2, 3, 4]: prod *= item
print(prod) # 24

s = "abcdef"
for x in s:
    print(x, end=" ") # a b c d e f 

for (a, b) in [(1, 2), (3, 4)]:
    print(a, "->", b) # 1 -> 2 3 -> 4

d = {"a": 1, "b": 2, "c": 5}
for key in d:
    print(key)  # a , b,  c
    print("key:", d[key])

>>> a, b, c = 1, 2, 3
>>> a, b, c
(1, 2, 3)

>>> for (a, b, c) in [(1,2,3), (4, 5, 6)]:
...     print(a, b, c)
...
1 2 3
4 5 6

>>> a, *b , c = (1, 2, 3, 4)
>>> a, b, c
(1, [2, 3], 4)

>>> for (a, *b, c) in [(1, 2, 3, 4), (5, 6, 7, 8)]:
...     print(a, b, c)
...
1 [2, 3] 4
5 [6, 7] 8

>>> for all in [(1, 2, 3, 4), (5, 6, 7, 8)]:
...     a, b, c = all[0], all[1:3], all[3]
...     print(a, b, c)
...
1 (2, 3) 4
5 (6, 7) 8

# 集合的交集
seq1 = "spam"
seq2 = "scam"
res = []
for seq_1 in seq1:
    if seq_1 in seq2:
        res.append(seq_1)
print(res)  # ['s', 'a', 'm']

while和range

>>> list(range(5)), list(range(2, 5)), list(range(0, 10, 2))
([0, 1, 2, 3, 4], [2, 3, 4], [0, 2, 4, 6, 8])

>>> for i in range(5):
...     print("i**2", i**2)
...
i**2 0
i**2 1
i**2 4
i**2 9
i**2 16

>>> L1 = [1, 2, 3, 4]
>>> L2 = [4, 5, 6, 7]
>>> zip(L1, L2)
<zip object at 0x000001FE7EB3CF08>
>>> list(zip(L1, L2))
[(1, 4), (2, 5), (3, 6), (4, 7)]

>>> for (x,y) in zip(L1,L2):
...     print(x,y, "->",x+y)
...
1 4 -> 5
2 5 -> 7
3 6 -> 9
4 7 -> 11


# map(function, iterable, ...)
Python 2.x 返回列表。
Python 3.x 返回迭代器。
>>> def square(x):
...     return x**2
...
>>> map(square, [1, 2, 3, 4])
<map object at 0x000001FE7EB423C8>
>>> list(map(square, [1, 2, 3, 4]))
[1, 4, 9, 16]
>>> map(lambda x:x ** 2, [1, 2, 3])
<map object at 0x000001FE7EB29748>
>>> list(map(lambda x:x ** 2, [1, 2, 3]))
[1, 4, 9]

>>> s="spam"
>>> for (offset, item) in enumerate(s):
...     print(item, "appears at offset", offset)
...
s appears at offset 0
p appears at offset 1
a appears at offset 2
m appears at offset 3

迭代器

代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

延迟计算或惰性求值 (Lazy evaluation)
迭代器不要求你事先准备好整个迭代过程中所有的元素。仅仅是在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合。

可迭代对象

  迭代器提供了一个统一的访问集合的接口。只要是实现了__iter__()或__getitem__()方法的对象,就可以使用迭代器进行访问。

  序列:字符串、列表、元组

  非序列:字典、文件

  自定义类:用户自定义的类实现了__iter__()或__getitem__()方法的对象

# 使用对象内置的__iter__()方法生成迭代器
>>> L = [1, 2, 3]
>>> I = L.__iter__()
>>> print(I)
<list_iterator object at 0x000001FE7EB42470>
>>> I.next()
>>> I.__next__()
1
>>> I.__next__()
2
>>> I.__next__()
3
>>> I.__next__()# 结果结果进入末尾是,则会引发StopIteration
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
# 内置函数创建迭代器
>>> L = [1, 2, 3]
>>> I = iter(L)
>>> I
<list_iterator object at 0x000001FE7EB29748>

>>> D = {"a":1,"b":2,"c":3}
>>> I = iter(D)
>>> next(I)
'a'
>>> next(I)
'b'
>>> next(I)
'c'
>>> next(I)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

列表生成器

想在列表的元素加上一个数x,[0,1,2,3,4,5,6,7,8,9],怎么样实现?

# 假设x =10
list_ = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
new_list = []
for i in list_:
    new_list.append(i + 10)
    
print(new_list) # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

list_1 = list(map(lambda x: x + 10, list_))
print(list_1) # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

list_2 = [x + 10 for x in list_]
print(list_2)  # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

什么是生成器?

通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator
生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。

生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器。
要创建一个generator,有很多种方法,第一种方法很简单,只有把一个列表生成式的[]中括号改为()小括号,就创建一个generator

#列表
list_3 = [i ** 2 for i in range(10)]
print(list_3)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 生成器
list_4 = (i ** 2 for i in range(10))
print(list_4)  # <generator object <genexpr> at 0x000002DBBFB02BA0>

怎么样访问生成器中的元素?可以通过__next__方法来访问元素。

list_4 = (i ** 2 for i in range(10))
print(list_4.__next__(), end=" ")  # 0
print(list_4.__next__(), end=" ")  # 1
print(list_4.__next__(), end=" ")  # 4

如果没有更多的元素的时候,系统会引发StopIteration, 正如上面代码中(可迭代对象)那样。
在这种情况,一般采用for循环来变遍历元素,生成器(generator)也是迭代器。

list_4 = (i ** 2 for i in range(10))
for i in list_4:
    print(i, end=" ")  # 0 1 4 0 1 4 9 16 25 36 49 64 81  

for循环来迭代,不需要关心StopIteration的错误,generator非常强大,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
例如下面的斐波那契数列,除第一个和第二个数外,任何一个数都可以由前两个相加得到:
1,1,2,3,5,8,12,21,34.....

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        a, b = b, a+b
        n = n + 1
        print(a, end=" ")


fib(10)  #  0 1 4 9 16 25 36 49 64 81 1 1 2 3 5 8 13 21 34 55 

函数也可以用generator来实现,上面我们发现,print(b)每次函数运行都要打印,占内存,所以为了不占内存,我们也可以使用生成器,这里叫yield。


def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a+b
        n = n + 1
        # print(a, end=" ")

a =fib(10)

print(a)
print(a.__next__(), end=" ")
print(a.__next__(), end=" ")
print(a.__next__(), end=" ")
print(a.__next__(), end=" ")
print("Test", end=" ")
print(a.__next__(), end=" ")
print(a.__next__(), end=" ")
print(a.__next__(), end=" ")
print(a.__next__(), end=" ")
result:
<generator object fib at 0x00000184EF692BA0>
1 1 2 3 Test 5 8 13 21 

用__next__()访问元素,防止StopIteration,需要进行异常处理。

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a+b
        n = n + 1
        # print(a, end=" ")

a =fib(10)

while 1:  # while 1 比 True效率高
    try:
        print(a.__next__(),end=" ")
    except StopIteration as e:
        break

# 上面的异常处理,正是for循环的处理的机制,就是不断的__next_()。
for i in [1,2,2]:
    pass
等价于:

首先获得Iterator对象: 
it = iter([1, 2, 2])
while 1:
try:
    print(it.__next__())
except StopIteration as e:
    break

可以使用isinstance()判断一个对象是否为可Iterable对象

from collections import  Iterable
print(isinstance({}, Iterable))
print(isinstance([], Iterable))
print(isinstance((), Iterable))
print(isinstance("abc", Iterable))
print(isinstance([x ** 2 for x in range(10)], Iterable))
print(isinstance(10, Iterable))


# True
# True
# True
# True
# True
# False

生成器都是Iterator对象,但list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)。把list、dict、dict、str变成Iterator(迭代器)使用iter函数。


from collections import Iterator
print(isinstance([], Iterator))  # False
print(isinstance(iter([]), Iterator))  # True

print(isinstance({}, Iterator))  # False
print(isinstance(iter({}), Iterator))  # True

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

小结:

  • 凡是可作用于for循环的对象都是Iterable类型;
  • 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
  • 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

yield的总结

  
(1):通常的for..in...循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文件。他可以是a = [1,2,3],也可以是a = [x*x for x in range(3)]。
它的缺点也很明显,就是所有数据都在内存里面,如果有海量的数据,将会非常耗内存。
  
(2)生成器是可以迭代的,但是只可以读取它一次。因为用的时候才生成,比如a = (x*x for x in range(3))。!!!!注意这里是小括号而不是方括号。
  
(3)生成器(generator)能够迭代的关键是他有next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。
  
(4)带有yield的函数不再是一个普通的函数,而是一个生成器generator,可用于迭代
  
(5)yield是一个类似return 的关键字,迭代一次遇到yield的时候就返回yield后面或者右面的值。而且下一次迭代的时候,从上一次迭代遇到的yield后面的代码开始执行
  
(6)yield就是return返回的一个值,并且记住这个返回的位置。下一次迭代就从这个位置开始。
  
(7)带有yield的函数不仅仅是只用于for循环,而且可用于某个函数的参数,只要这个函数的参数也允许迭代参数。
  
(8)send()和next()的区别就在于send可传递参数给yield表达式,这时候传递的参数就会作为yield表达式的值,而yield的参数是返回给调用者的值,也就是说send可以强行修改上一个yield表达式值。
  
(9)send()和next()都有返回值,他们的返回值是当前迭代遇到的yield的时候,yield后面表达式的值,其实就是当前迭代yield后面的参数。
(10)第一次调用时候必须先next()或send(),否则会报错,send后之所以为None是因为这时候没有上一个yield,所以也可以认为next()等同于send(None)

参考文档

函数

一个函数就是将一些语句集合在一起的部件,他们不止一次第在程序中运行,函数还能计算出一个返回值,并且能够改变作为函数输出的参数,而且这些参数在代码运行时也许每次都不相同。函数能提高应用的模块性,和代码的重复利用率。

定义函数,有下面的基本规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
  • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
    基本形式
def <name>(arg1, arg2, arg3,...):
    <satatements>

参数

其中函数有3种参数:

  • 普通参数
  • 默认参数
  • 动态参数

普通参数

def func(name, age):
    print("name and age is :", name, ",", age)

func("ycj", 18)

默认参数

def func(name, age=20):  # (name="ycj",age) Error 默认参数 从后面参数经行赋值,不能从前面开始
    print(name, age)
      
func("ycj")

动态参数

def func1(*args):
    return args

print(func1(1, "a", 456))  # (1, 'a', 456)
list_ = ["a", "b", "c", 12, 45.3]
print(func1(*list_))  # ('a', 'b', 'c', 12, 45.3)

def func(**args):
    return args


print(func(name="ycj", age =12))  # {'name': 'ycj', 'age': 12}

dict_ = {"name": "ycj", "age": 12, "work": "farmer"}

print(func(**dict_))  # {'name': 'ycj', 'age': 12, 'work': 'farmer'}


def func2(*args, **kwargs):
    return args, kwargs


a = func2("devil","work", 12, name="ycj", age=20)  # 数据的类型位置不能错 例如( name="ycj", age=20,"devil","work", 12 )error
dict_ = {"name":"ycj", "age": 20}
list_ = [12, 35, "name"]

b = func2(*list_, **dict_)
print(a)  # (('devil', 'work', 12), {'name': 'ycj', 'age': 20})
print(b)  # ((12, 35, 'name'), {'name': 'ycj', 'age': 20})

作用域

在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域。python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量能被访问的范围。即Python变量的作用域由变量所在源代码中的位置决定。

高级语言使用数据类型的过程

  • 声明变量:让编辑器知道有这一个变量的存在
  • 定义变量:为不同数据类型的变量分配内存空间
  • 初始化:赋值,填充分配好的内存空间
  • 引用:通过引用对象(变量名)来调用内存对象(内存数据)

作用域的产生

Python与C/c++有着很大的区别,在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念

def func():
    i = 0
    print(i)
print(i)  # NameError: name 'i' is not defined

在作用域中定义的变量,一般只在作用域中有效。 需要注意的是:在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域。

if 1:
    i = 0
    print(i)

print(i)  # 0 i在if中定义,但是在if外面还是能够使用

作用域的类型 ###:

在Python中,使用一个变量时并不严格要求需要预先声明它,但是在真正使用它之前,它必须被绑定到某个内存对象(被定义、赋值);这种变量名的绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量。

L(local)局部作用域

局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。
注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。

# 将局部作用域变为全局作用域 加上global
def func():
    # i=0  # 局部作用域
    global i  # 不能直接赋值 将i变成全局变量
    print("i=", i)
    i = 0
    print(i)

i = 500
func()
print(i)

answer:
i= 500
0
0

E(enclosing)嵌套作用域

E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。主要是为了实现Python的闭包,而增加的实现。


def f1():
    x = 88  # local
    def f2():
        print(x)

    f2()
f1()  # 88

G(global)全局作用域

即在模块层次中定义的变量,每一个模块都是一个全局作用域。也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。
注意:全局作用域的作用范围仅限于单个模块文件内

B(built-in)内置作用域

系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。

Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)] on win32
>>> import builtins
>>> dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
>>>

变量名解析LEGB法则

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域
LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会出发NameError错误。

例子如下:

x = 100  # 全局作用域
def func():
    i = 0  # 局部作用域
    print(i)


def f1():
    x = 88
    def f2():
        print(x)
    return f2

# action = f1()
# action()        <==>f1()()  # f2的函数的调用动作的运行是在f1运行后发生的,f2记住了在f1
# 嵌套作用域x,尽管f1已经不处于激活状态
f1()()
# 函数与函数之间的嵌套
def f2(x):
    print(x)

def f1():
    x = 88
    f2(x)
f1()  # 88

nonlocal语句

nonlocal语句允许对嵌套的函数作用域的名称赋值,并且把这样的名称的作用域查找限制在嵌套的def中。直接效果是更加的直接和可靠地实现了可更改的作用域信息。

global和nonlocal查找规则

  • global使得作用域查找从嵌套的模块的作用域开始,并且允许对哪里的名称赋值。如果名称不存在在模块中,作用域查找继续到内置的作用域,但是,对于全局的名称的赋值总是在模块的作用域中创建或修改它们。
  • nonlocal限制作用域查找只是嵌套的def,要求名称语句存在那里,并且允许对它们进行赋值。作用域查找不会继续到全局或内置的作用域。
def tester(start):
    state = start
    def nested(label):
        print(label, state)
        state += 1
    return nested

f = tester(0)
f("spam")  # Error
# UnboundLocalError: local variable 'state' referenced before assignment

def tester(start):
    state = start
    def nested(label):
        nonlocal state  # 
        print(label, state)
        state += 1
    return nested

f = tester(0)
f("spam")
f("test")
f(123)
#---------
spam 0
test 1
123 2

边界情况

和global语句不同,当执行一条nonlocal语句时,nonlocal名称必须已经在一个嵌套的def作用域中赋值过,否则将得到一个error,不能通过在嵌套的作用域中赋给它们一个新值来创建它们。

def tester(start):
    def nested(label):
        nonlocal state
        state = 0
        print(label, state)
        
    return nested

# SyntaxError: no binding for nonlocal 'state' found]

def tester(start):
    def nested(label):
        global state
        state = 0
        print(label, state)

    return nested

f = tester(0)
f("spam")
f("test")
f(123)
#______________________________
spam 0
test 0
123 0

与全局共享状态

python2.6中实现了nonlocal效果的一种通用的方法也是比较早的方法,就是直接把状态移出全局变量作用域(嵌套对模块):

def tester(start):
    global state
    state = start
    def nested(label):
        global state
        print(label, state)
        state += 1
    return nested
state = 10
f = tester(0)
f("spam")
f("test")
f(123)
print(state)
#________________________
spam 0
test 1
123 2
3

使用类的状态

class tester:
    def __init__(self, start):
        self.state = start
        
    def nested(self, label):
        print(self.state, label)
        self.state += 1


F = tester(0)
F.nested("Ycj")
F.nested("Devil")
#____________________
0 Ycj
1 Devil

使用函数属性的状态

我们有时候可以使用函数的属性实现与nonlocal相同的效果--用户定义的名称直接附加给函数,它用附加给嵌套的函数个一个属性替代了nonlocal,它允许从嵌套的函数之外访问状态变量(使用nonlocals,我们只能在嵌套的def看见状态变量):

def tester(start):
    def nested(label):
        print(label, nested.state)

        nested.state += 1

        nested.state = start
        return nested
#运行有问题
F = tester(0)
F('spam')  # TypeError: 'NoneType' object is not callable

摘自博客

代码中定义的一个名称的位置决定了它的大部分的含义。python的参数传递的概念,即对象作为输入发送给函数的方式,参数(argument,也叫做paramete)赋值给一个函数中的名称, 但是,它们更多的是与对象引用相关,而不是变量作用域相关。

传递参数

  • 参数传递是通过自动将对象赋值给本地变量名来是实现的。
  • 在函数内部的参数名的赋值不会影响调用者。
  • 改变函数的可变对象参数的值也许会对调用者有影响。

python通过赋值进行传递的机制与c++的引用参数选项并不完全相同,在实际中,它与c语言的参数传递模型相当的相似。

  • 不可变参数"通过值"进行传递。
  • 可变对象是通过"指针"进行传递的。

参数和共享引用

>>> def changer(a,b):
...     a = 2
...     b[0]="spam"
...
>>> x = 1
>>> L = [1, 2]
>>> changer(x, L)
>>> x, L
(1, ['spam', 2])
  • a在函数作用域内的本地变量名,第一个赋值对函数调用者没有影响,它仅仅把本地变量a修改为一个引用一个完全不同的对象,并没有改变调用者的作用域中的名称x的绑定。
  • b是一个本地变量名,但是它被传递给一个可变的对象(在调用者作用域中叫做L的列表)。因为第二个赋值是一个在原处发生的对象的改变,对函数中b[0]进行赋值的结果会在函数返回中影响L的值。

实际上,changer中的第二条的赋值语句没有修改b,我们修改是b当前所引用的对象的一部分。这种原处修改,只有在修改的对象并函数调用的生命更长的时候,才会影响到调用者。名称L也没有改变-它仍然引用同样的、修改后的对象,但是,就好像L在调用后变化了一样。因为它引用值已经在函数中修改过了。

表名函数被调用后,函数代码在运行前,变量名/对象所存在的绑定关系。

技术分享图片

特定参数的匹配模型

函数参数匹配表

语法 位置 解释
func(values) 调用者 常规参数:通过位置进行匹配
func(name=values) 调用者 关键字参数:通过变量名进行匹配
func(*sequence) 调用者 以nam传递所以的对象,并作为独立的基于位置参数
func(**dict) 调用者 以name成对的传递所有的关键字/值,并作为独立的关键字参数
def func(name) 函数 常规参数:通过位置或变量名进行匹配
def func(name=values) 函数 默认参数值,如果没有在调用者中传递的话
def func(*name) 函数 匹配并收集,(在元组中)所有包含位置的参数
def func(**name) 函数 匹配并收集,(在字典中)所有包含位置的参数
def func(*args, name) 函数 参数必须在调按照关键字传递
def func(*, name=value) 函数 python3.0

函数的参数出现的位置:

  • 在函数调用中,参数必须也此顺序出现:任何位置的参数(values),后面跟着任何的关键字参数(name=value)和*sequence形式的组合,后面在在跟着**dict的形式出现。
  • 在函数的头部,参数必须也此顺序出现:任何一般参数(name),紧跟着任何的默认参数(name=value),如果有的话,后面是*name(或者是python3.0中的*)的形式,后面跟着name或name=value keyword-only参数(python3.0),后面跟着**name形式。

关键字参数和默认关键字参数的实例

>>> def f(a, b, c):
...     print(a,b, c)
...
>>> f(1, 2, 3)
1 2 3
>>>

>>> def f1(a=10, c= 20, b = 50):  # 关键字参数
...     print(a,b, c)
...
>>> f1()
10 50 20
>>> f1(100, 200, 300)
100 300 200
>>> f1(10)
10 50 20
>>>
>>> def f2(a, b, c=12):  # 默认参数
...     print(a, b, c)
...
>>> f2(10, 20)
10 20 12
>>> f2(10, 100, 1000)
10 100 1000
>>>

>>> def f3(a,b=2, c=3):
...     print(a, b, c)
...
>>> f3(10)
10 2 3
>>> f3(a = 112, c = 456)
112 2 456
>>>

>>> def f4(*args):  # 任意参数 返回元组
...     print(args)
...
>>> f4(1, 2, 3, 4)
(1, 2, 3, 4)
>>> f4()
()
>>> a=["a", 12, True, 3.0]
>>> f4(*a)
('a', 12, True, 3.0)
>>>
>>> b =(1, 2, "a",True, 3.0)
>>> f4(*b)
(1, 2, 'a', True, 3.0)

>>> def f5(**args):  # 返回字典的形式
...     print(args)
...
>>> f5(a=1, b=2)
{'a': 1, 'b': 2}
>>> f5()
{}

>>> a={"name":"ycj", "age":18}
>>> f5(**a)
{'name': 'ycj', 'age': 18}

>>> def f6(a, *pargs, **kargs):
...     print(a, pargs, kargs)
...
>>> f6(1, 2, 3, x=1, y=2)
1 (2, 3) {'x': 1, 'y': 2}
>>> f6(1, 2, 3,5, 7, x=1, y=2)
1 (2, 3, 5, 7) {'x': 1, 'y': 2}
>>>
# 解包参数
>>> def f7(a, b, c, d):
...     print(a,b, c,d)
...
>>> args =(1, 2)
>>> args += (3, 4)
>>> f7(*args)
1 2 3 4
>>> f7(*(1, 2), **{"d":4, "c":4})
1 2 4 4
>>> f7(1, *(1, 2), 4)
1 1 2 4
>>> f7(1, *(2,), c=3, **{'d':4})
1 2 3 4

keyword-only参数

python3.0把函数头部的排序规则通用化了,允许我们指定keyword-only参数-即必须按照关键字传递并且不会由一个参数来填充参数,如果想要一个函数即处理任意多个参数,也接收可以的配置选项的话,这是很有用的。
keyword-only参数的编码为命名的参数,**出现在参数的列表中的*args之后,所有这些参数都必须在调用中使用关键字来传递**。例如下面的代码中,a 可以按照名称和位置传递,b收集任何的额外的位置参数,并且c必须按照关键字传递。

>>> def kownly(a, *b, c):
...     print(a, b, c)
>>> kownly(1, 2, c=3)
1 (2,) 3
>>> kownly(a=1, c=3)
1 () 3

>>> def kwonly(a,*, b, c):
...     print(a, b, c)
...
>>> kwonly(1, c= 2, b = 7)
1 7 2
>>> kwonly(1, 2, 3)
TypeError: kwonly() takes 1 positional argument but 3 were given
>>> kwonly(1)
TypeError: kwonly() missing 2 required keyword-only arguments: 'b' and 'c'

对keyword-only使用默认值,即使在函数的头部中的*后面,在下面的的代码中,a可以按照名称或位置,而b和c是可选的,但是如果使用的话必须的关键字进行传递:

>>> def knowly(a,*, b="spam", c="ham"):
...     print(a, b,c)
...
>>> knowly(1)
1 spam ham
>>> knowly(1, c = 1)
1 spam 1
>>> knowly(1, b="a", c="c")
1 a c
>>> knowly(1, 2) # c要用关键字进行传递
TypeError: knowly() takes 1 positional argument but 2 were given

>>> def kownly(a, *, b, c="spam"):
...     print(a, b, c)
...
>>> kownly(1, b = "eggs")
1 eggs spam
>>> kownly(1, b = "a", c=1)
1 a 1
>>> knowly(1, 2,3) # *后面的参数必须用关键字进行传递 b= 2
TypeError: knowly() takes 1 positional argument but 3 were given

排序的规则

keywor-only参数必须在一个单个星号后面指定,而不是两个星号-命名的参数不能出现在**args任意的关键字形式的后面,并且一个双星号不能独自出现在参数列表中,以下的两种形式将发生错误。

>>> def kownly(a, **args, b, c):
SyntaxError: invalid syntax
>>> def kownly(a, **, b, c):
SyntaxError: invalid syntax

一个函数的头部,keyword-only参数必须编写在**args任意的关键字之前,其在*args任意位置形式之后,当二者都有的时候。一个参数出现在*args之前,它可以是默认位置参数,而不是keyword-only参数:

>>> def f(a, *b, **d, c=2):print(a, b,c , d)
SyntaxError: invalid syntax

>>> def f(a, *b, c=2, **d):print(a, b,c , d)
...
>>> f(1, 2, 3, x = 4, y=5)
1 (2, 3) 2 {'x': 4, 'y': 5}

>>> f(1, 2, 3, x = 4, y=5, c=7)
1 (2, 3) 7 {'x': 4, 'y': 5}
>>> def f(a, c=6, *b, **d):print(a, b, c, d) # c is not keyword-only
...
>>> f(1, 2, 3, x =4)
1 (3,) 2 {'x': 4}

在函数调用中,类似的排序规则也是成立的:当传递的keyword-only参数的时候,他们必须出现一个**args形式之前。keyword-only参数可以编写在*args之前或者之后,并且可以包含**args之前或者之后,并且可以包含在**args中:

>>> def f(a,*b,c=6,**d):
...     print(a,b,c,d)
...
>>> f(1, *(2,3),**dict(x=4,y=5), c=7)
1 (2, 3) 7 {'x': 4, 'y': 5}
>>> f(1, *(2,3),c = 7,**dict(x=4,y=5))
1 (2, 3) 7 {'x': 4, 'y': 5}
>>> f(1,c = 7, *(2,3),**dict(x=4,y=5))
1 (2, 3) 7 {'x': 4, 'y': 5}
>>> f(1, *(2,3),**dict(x=4,y=5, c=7))
1 (2, 3) 7 {'x': 4, 'y': 5}
>>>

为什么使用keyword-only参数

它们很容易允许一个函数即接收任意多个要处理的位置参数,也接受作为关键字传递的配置选项,尽管他们的使用是可选的,没有keyword-only参数的话,要为这样的选项提供默认值并验证没有传递多余的关键字则需要额外的工作。
假设一个函数处理一组传入的对象,并且允许传递的一个跟踪标志:

process(x, y, z)
process(x,y,notify=True)

如果没有keyword-only参数的话,我们必须使用*args和**args,并且手动地检查关键字,但是,有了keyword-only参数,需要的代码就会更少。下面的语句通过notify保证不会有位置参数错误匹配,并且要求它 如果传递则作为一个关键字传递:

def processed(*args,notify=True): ...

min调用

def min1(*args):
    res = args[0]
    for arg in args[1:]:
        if arg < res:
            res = arg
    return res


def min2(first, *rest):
    for arg in rest:
        if arg < first:
            first = arg
    return first


def min3(*args):
    tmp = list(args)
    tmp.sort()
    return tmp[0]


print(min1(3, 4, 7, 2))
print(min2("bb", "aa"))
print(min3([1, 11], [22, 33], [8, 8]))

#————————————————————————
2
aa
[1, 11]

升级,将max和min一个函数。

def minmax(test, *args):
    res = args[0]
    for i in args[1:]:
        if test(i, res):  # 如果为真,执行下去(传入一个判断函数)
             res = i
    return res

def lessthan(x, y): return x < y # 最小值


def grtrthan(x, y): return x > y  #最大值

print(minmax(lessthan, 4, 7, 9, 5, 1, 3))
print(minmax(grtrthan, 4, 7, 9, 5, 1, 3))

函数的高级话题

函数设计的概念

  • 耦合性:对于输入使用参数并且对于输出使用return语句。
  • 耦合性:只有在真正必须的情况下使用全局变量。
  • 耦合性:不要改变可变类型的参数,除非调用者希望这样做。
  • 聚合性:每一个函数都应该有一个单一的、统一的目标。
  • 大小:每一个函数应该相对较小。
  • 耦合:避免直接改变在另一个模块的文件中的变量。

技术分享图片

递归函数

变写一个sum求和的函数,递归方式:

def sum_(L):
    if not L:
        return 0
    else:
        return L[0] + sum_(L[1:])

print(sum_([1, 2, 3, 4]))  # 10
# 其他的方案
def mysum(L): return L[0] if len(L) == 1 else L[0] + mysum(L[1:])

def mysum(L): return 0 if not L else L[0] + mysum(L[1:])

def mysum(L):   # L = L[0] + L[1:]
    first, *rest = L
    return first if not rest else first + mysum(rest)


print(mysum([1, 2, 3, 4]))  # 10

# 函数之间的嵌套
def mysum(L):
    if not L:
        return 0
    else:
        return nonempty(L)


def nonempty(L):
    return L[0] + mysum(L[1:]) 


print(mysum([1, 2, 3, 4]))  #10

在python中,递归不像在Prolog或Lisp这样更加的深奥的语言中那样常用,因为python强调像循环这样的简单的过程式的语句,循环通常更加的自然。例如下面while循环,使得一些问题更加的具体一些,并且它不需要定义一个支持递归调用的函数。

L =[1, 2, 3, 4]
sum_=0
while L: # 选择L 如果遍历完,退出
   sum_ += L[0]
   L = L[1:]

print(sum_)

处理任何结构

def sumtree(L):
    tot = 0
    for i in L:
        if not isinstance(i, list):  # 判断是不是list类型
            tot += i
        else:
            tot += sumtree(i)

    return tot


L = [[1], [1, 2, 2, [4, 5]]]

print(sumtree(L)) # 15

函数间接调用

>>> def show(message):
...     print(message)

...
>>> show("Show")
>>> s = show  #函数名直接是一个对象的引用,就可以自由地把这个对象赋值给其他的名称并且通过任何引用调用它
>>> s("SHOW")
SHOW
>>>
>>> def indirect(func,arg):
...     func(arg)
...
>>> indirect(show, "Test indirect")  # 调用show函数
Test indirect

函数的内省

例如,一旦我们创建一个函数,可以向往常一样调用它:

>>> def func(a):
...     b = "YANG"
...     print(b * a)
...
>>> func(3)
YANGYANGYANG

但是,调用表达式只是定义在函数对象上工作上的一个操作,我们也可以通过通用地检查它们的属性(python3.x运行的)

>>> func.__name__
'func'
>>> dir(func)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>>

这样的属性可以用来直接把状态信息附加给函数对象,而不必使用全局、非本地和类等其他的技术。和非本地不同,这样的属性可以在函数自身的任何的地方访问,从某种意义上来讲,这是模拟其他语言中的"静态本地变量"的一种方式-这种变量的名称对有一个函数来说是本地的,但是,其值的在函数退出后仍然保留。属性与对象相关而不是与作用域相关,但是直接效果是类似的。

Python3.0函数的注解
函数注解编写在def头部行,就像与参数和返回值相关的任何表达式一样,对于参数,它们出现在紧跟参数名之后的冒号之后,对应返回值,它们编写于紧跟在参数列表之后的一个->之后,例如下面的代码中:

>>> def func(a:"spam", b:(1, 10), c:float) ->int:
...     return a + b + c
...
>>> func(1, 2, 3)
6
>>> func("a", "v", "c")
'avc'
>>> func(["a"], "c", "d")

调用一个注解函数,python将它们收集到的字典中并且将他们附加给函数对象本身,参数名变成了键,如果编写了返回值注解的话, 它存储在"return"下,为注解键的值则赋给了注解表达式的结果:

>>> def func(a:"spam",b,c:99):
...     return a + b + c
...
>>> func(1, 2, 2)
5
>>> func.__annotations__
{'a': 'spam', 'c': 99}
>>> for arg in func.__annotations__:
...     print(arg, '->', func.__annotations__[arg])
...
...
a -> spam
c -> 99

编写了注解的话,仍然可以对参数使用默认值-注解(及其:字符)出现在默认值(及其=字符)之后。例如a:"spam"=4 表示a的默认值是4,注解是字符串"spam"

>>> def func(a:"spam"=4, b:(1, 10)=5, c:float = 6)->int:
...     return a + b + c
...
>>> func(1, 2, 3)
6
>>> func()
15
>>> func(a=12, c=10)
27
>>> func.__annotations__
{'a': 'spam', 'b': (1, 10), 'c': <class 'float'>, 'return': <class 'int'>}
>>>

注解在def语句中语句中才有效,在lambda中是无效的,因为lambda的语法已经限制了它所定义的函数的工具。

lambda(匿名函数)

lambda表达式

lambda的一般形式是关键字lambda,之后是一个或者是多个参数(与一个def头部内因括号括起来的参数列表及其相似),紧跟的是一个冒号,之后是表达式“

lambda argument1,argment2...:expression using arguments

lambda表达式所返回的函数对象与由def创建并赋值后的函数对象工作起来是完全一样的,但是lambda有一些不同之处让其在扮演特定的角色时很有用。

  • lambda是一个表达式,而不是一个语句。
  • lambda的主体是一个单个的表达式,而不是一个代码块。
>>> def func(x, y, z):
...     return x + y + z
...
>>> func(1, 1, 1)
3
>>> f = lambda x, y, z: x + y + z  # lambda表达式
>>> f(1, 1, 1)
3
>>>
>>> f = lambda x="a", y="b", z="c": x + y + z # 带默认值
>>> f()
'abc'
>>> f(1,2,3)
6
>>>

在函数中嵌套lambda表达式:

def knights():
    title = "sir"
    actions = lambda x: title + " " + x
    return actions

f = knights()
print(f("Tom"))  # sir Tom

lambda起到了一种函数速写的作用,允许在使用代码内嵌套一个函数的定义。你可以完全可以用def代替,但是在你仅需要嵌入小段可执行代码的情况下它们会带来一个更加简洁的代码结构。

L = [

    lambda x: x ** 2,
    lambda x: x ** 3,
    lambda x: x ** 4
]

for f in L:
    print(f(2))

print(L[2](8))  # L[2]找到相对应的函数->x**4 8 ** 4 = 4096


# 也可以用def定义的方式进行定义函数
def f1(x): return x ** 2
def f2(x): return x ** 3
def f3(x): return x ** 4

L = [f1, f2, f3]

for f in L:
    print(f(2))
    
print(L[2](8))   # 4096

可以用python中的字典或者其他的数据结构来构建更多种类的行为,从而做跟多的事情

Key = "get"

f = {"already": (lambda x: x ** 2),
     "get": (lambda x: x + 10),
     "ones": (lambda x: x ** 3)}[Key](10)

print(f) #20

不要让你的代码变得晦涩难懂
如果你想要在lambda表达式中进行print,直接编写sys.stdout.write(str(x) + ‘\n‘)这个表达式,而不是直接使用print(x)这样的语句,例如我们知道到三元表示一样,一些对等的但是需要使用的技巧的and/or.

if  a:
    b
else:
    c
# 下面进行模拟
 b if a else c
((a and b) or c)

import sys
showall = lambda x: list(map(sys.stdout.write, x))
t = showall(['spam\n', 'a\n', 'b\n'])
print(t)  
#———————————————————————————— 
spam
a
b
[5, 2, 2]
#————————————————————————————
showall = lambda x: [sys.stdout.write(line) for line in x]
t = showall(('a\n', 'b\n', 'c\n'))
a
b
c
[2, 2, 2]

嵌套lambda和作用域

lambda出现在def中,并且在上层函数调用的时候,嵌套的lambda能够获取到上层函数作用域中的变量名x的值。

>>> def actions(x):
...     return (lambda y: x + y)
...
>>> act = actions(1)
>>> act(12)
13

>>> def action(x):
...     return (lambda y:x + y)
...
>>> act = action(12)
>>> act
<function action.<locals>.<lambda> at 0x00000244314C6730>
>>> act(10)
22
>>> ((lambda x:(lambda y: x+y)))(88)(4)
92

在序列中映射函数:map

假设要做一件事情就是对每一个元素进行一个操作并把其结果结合起来,例如,有一个list counter中更新每一个元素,我们可以运行for循环遍历,对元素进行操作;

counters = [1, 2, 3, 4]
updated = []
for data in counters:
    updated.append(data + 10)

print(updated)

python的内置函数,map函数会对每一个序列对象中的元素被应用被传入的函数,并且返回一个包含了所有函数调用的结果的一个列表:

>>> def func(x): return x + 10
...
>>> list(map(func, [1, 2, 3, 4]))
[11, 12, 13, 14]

>>> list(map((lambda x: x + 10), [1, 2, 3]))
[11, 12, 13]
>>> list(map(pow, [1, 2, 2], [4, 5, 6])) # 内置函数pow(平方)
[1, 32, 64]

函数式编程工具:filter和reduce

map函数是用来进行函数式编程的这类工具中最简单的内置函数代表。filter对数据进行过滤,以及对每对元素都应用函数并运行到最后的结果(reduce),range和filter都返回可迭代的对象,可以用转换为list进行显示其结果。

例如找出大于0的数据用filter:

>>> range(-10, 10)
range(-10, 10)
>>> list(range(-10, 10))
[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
>>> list(filter((lambda x: x >0), range(-10, 10)))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
# 也可以自己定义函数实现
def func():
    res = []
    for i in range(-10, 10):
        if i > 0:
            res.append(i)

    return res
print(func())  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

reduce测试

>>> from functools import reduce
>>> reduce((lambda x, y: x + y), [1, 2, 3, 4])
10
>>> reduce((lambda x, y: x * y), [1, 2, 3, 4])
24
>>>
# 也可以自己定义函数实现:
def func(L):
    res = L[0]
    for i in L[1:]:
        res += i
    return res
L=[1, 2, 3]
print(func(L))  # 6

def myreduce(function, sequence):
    tally = sequence[0]
    for next in sequence[1:]:
        tally = function(tally, next)
    return tally

print(myreduce(lambda x, y: x + y, [1, 2, 3, 4, 5])) # 15

import operator, functools
res = functools.reduce(operator.add, [2, 4, 6])
res1 = reduce((lambda x, y: x + y), [2, 4, 6])

print(res1)

迭代和解析

列表解析与map
python的内置函数ord(),返回单个字符的ASCII整数的编码(chr就是ord的逆过程,将ASCII装换为字符)

# 将字符's'装换为ASCII码:
>>> ord('s')
115
# 将ASCII转换为字符:
>>> chr(117)
'u'
# 将字符串装换为ASCII码:
>>> res = []
>>> for i in "Ycj":
...     res.append(ord(i))
...
>>> res
[89, 99, 106]

# map实现
>>> list(map((lambda x: ord(x)), "Ycj")) 
[89, 99, 106]
>>> list(map(ord, "Ycj"))  
[89, 99, 106]

>>> a = [ord(x) for x in "Ycj"]
>>> a
[89, 99, 106]

# 将1-9之间的数据平方

# map方式
>>> list(map(lambda x: x**2, range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
import numpy as np
>>> list(map(np.square,range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# for循环
>>> [i ** 2 for i in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

嵌套循环

# 想在1-9之间找出奇数
>>> res = []
>>> for i in range(10):
...     if i%2 == 1:
...             res.append(i)
...
>>> res
[1, 3, 5, 7, 9]
filter方式:
>>> list(filter((lambda x: x% 2 == 1), range(10)))
[1, 3, 5, 7, 9]
for循环方式:
>>> [i for i in range(10) if i%2==1]
[1, 3, 5, 7, 9]

升级:将挑选的奇数平方

>>> res = []
>>> for i in range(10):
...     if i % 2 == 1:
...             res.append(i ** 2)
...
>>> res
[1, 9, 25, 49, 81]
# map和filter结合:
>>> list(map((lambda x: x**2), filter((lambda y: y %2 == 1), range(10))))
[1, 9, 25, 49, 81]
# for循环
>>> [x ** 2 for x in range(10) if x % 2 == 1]
[1, 9, 25, 49, 81]

# 奇偶数的组合
>>> [(x, y) for x in range(5) if x % 2 ==0 for y in range(5) if y % 2 == 1]
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
# 如果用嵌套for循环来实现
res = []
for x in range(5):
    if x % 2 == 0:
        for y in range(5):
            if y % 2 == 1:
                res.append((x, y))

print(res)  # [(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
# 通过for嵌套会看到,条理更加的清晰,但是显得臃肿, 列表解析更加的简洁,但是条理没有for循环那么清晰。

列表解析和矩阵

# 矩阵操作
M = [
    [1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]
]

print(M[1], M[1][1])  # [4, 5, 6] 5


a =[row[1] for row in M]
print(a)  # [2, 5, 8]
a = [M[i][i] for i in range(len(M))]
print(a)  # [1, 5, 9]

a = [M[row][col] * N[row][col] for row in range(len(M)) for col in range(len(N))]
print(a)  # [7, 16, 27, 36, 30, 18, 21, 16, 45]

a = [[M[row][col] * N[row][col] for row in range(len(M))] for col in range(len(N))]

print(a)  # [[7, 36, 21], [16, 30, 16], [27, 18, 45]]

理解列表解析

列表的解析,特别是嵌套的时候,会显得很难理解,要保持代码是简洁,两者是相对的,对于运行情况的下的考虑,map调用的比等效的for循环要快两倍,而列表解析往往比map调用稍快一些,速度上的差距来自于底层的实现上,map和列表解析是基于c语言的速度来运行的,比python的for循环代码在pvm中布进运动要快的多。

# 在文件操作中,readlines方法返回的换行符\n结束的行。

>>> open('F:\\code\python\\test1\\log.txt','r', encoding='utf-8').readlines()
['aaa\n', 'bbb\n', 'ccc\n']

# 如果我们不需要这个换行符"\n",可以使用rstrip()方法,去除换行符

>>> [line.rstrip() for line in open('F:\\code\python\\test1\\log.txt','r', encoding='utf-8').readlines()]
['aaa', 'bbb', 'ccc']

>>> [line.rstrip() for line in open('F:\\code\python\\test1\\log.txt','r', encoding='utf-8')]
['aaa', 'bbb', 'ccc']

>>> list(map((lambda line:line.rstrip()), open('F:\\code\python\\test1\\log.txt','r', encoding='utf-8')))
['aaa', 'bbb', 'ccc']

在python3.0中map和列表解析的最大的区别是:map是一个迭代器,根据需求产生结果:为了同样实现内存节省,列表解析必须编码为生成器表达式。

迭代器:生成器

python对延迟提供了很多的支持-它提供的结果是什么时候产生结果,而不是立即产生结果,特别地,有两种 语言结构尽可能度延迟创建的结果。

  • 生成器函数:编写为常规的def语句,但是使用yield 语句返回一个结果,在每次的结果之前挂起和继续他们的状态。
  • 生成器表达式类似于列表解析,但是,它们返回按需产生的结果的一个对象,而不是构建一个结果列表。

生成函数的应用

定义一个生成器函数,这个函数会用不断的生成一系列数字的平方。

>>> def gensquares(N):
...     for i in range(N):
...             yield i ** 2
...
>>> gensquares(10)
<generator object gensquares at 0x000002644CEF86D0>
>>> x = gensquares(10)
>>> x.__next__()
0
>>> x.__next__()
1
>>> x.__next__()
4
>>> x.__next__()
9
>>> x.__next__()
16
>>> x.__next__()
25
>>> x.__next__()  # 当元素访问完后 在__next__()会产生StopIteration
# 也可以for循环访问
>>> for i in gensquares(10):
...     print(i,end='-')
...
0-1-4-9-16-25-36-49-64-81
# map:
>>> for x in map((lambda x: x** 2),range(10)):
...     print(x, end=" ")
...
0 1 4 9 16 25 36 49 64 81 

生成器协议:send 和 next

pythion2.5,生成器函数协议中增加一个send的方法,send方法生成一系列结果的下一个元素,有点想__next__()方法,它提供了一种调用者与生成器之间进行通信的方法,从而能影响它的操作。
yield是一个表达式形式,可以返回传入的元素来发送,而不是语句。表达式必须包含在括号内(x = yield y) + 42,除非它的赋值语句右边的唯一一项(x = yield)。

>>> def gen() :
...     for i in range(10):
...             x = yield i
...             print(x)
...
>>> G = gen()
>>> next(G)
0
>>> next(G)
None
1
>>> next(G)
None
2
>>> G.send(77)
77
3
>>> G.send(88)
88
4
>>

生成器表达式

生成器表达式就像一般的列表解析一样,但是他们是()中,而不是[]中。

>>> [x ** 2 for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> (x **  2 for  x in range(10))
<generator object <genexpr> at 0x000002644CEF86D0>
# 可以转换为list进行元素显示
>>> list((x **  2 for  x in range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

一般不会使用next迭代器来操作生成器表达式。而是用for循环,会自动触发。

>>> for num in (x ** 2 for x in range(4)):
...     print(num,end=" ")
...
0 1 4 9 

迭代工具模拟zip和map

>>> s1 = "abc"
>>> s2 = "123"
>>> list(zip(s1, s2))
[('a', '1'), ('b', '2'), ('c', '3')]
>>> list(zip([-2, 1, 0, 5]))
[(-2,), (1,), (0,), (5,)]
>>> list(map(abs, [-1, 2, -5, 4]))
[1, 2, 5, 4]
>>> list(map(pow, [1, 2, 3], [4, 5, 6, 7]))
[1, 32, 729]
>>> list(zip([1, 5, 6], [4, 2]))
[(1, 4), (5, 2)]

模拟map函数

def mymap(func, *seqs):
    res = []
    for args in zip(*seqs):              # print(*args)    -2, -1, 0, 1, 2
        res.append(func(*args))
    return res


print(mymap(abs, [-2, -1, 0, 1, 2]))

>>> def mymap(func, *seqs):
...     return [func(*args) for args in zip(*seqs)]
...
>>> mymap(abs, [-1, 2, -8, -10])
[1, 2, 8, 10]

>>> def mymap(func,*seqs):
...     res = []
...     for args in zip(*seqs):
...             yield func(*args)
...
>>> mymap(abs, [-10, 20, -123])
<generator object mymap at 0x000002644CEF86D0>
>>> list(mymap(abs, [-10, 20, -123]))
[10, 20, 123]

模拟zip函数

def myzip(*seqs):
    seqs = [list(s) for s in seqs]  #  [['a', 'b', 'c'], ['1', '2', '3']
    print(seqs)
    res = []
    while all(seqs): # all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。
元素除了是 0、空、FALSE 外都算 TRUE
    
        res.append(tuple(s.pop(0) for s in seqs))


    return res
print(myzip("abc", "123")) # [('a', '1'), ('b', '2'), ('c', '3')]
print(list(zip("abc", "123"))) #[('a', '1'), ('b', '2'), ('c', '3')]


def mymapPad(*args, pad=None):
    seqs = [list(s) for s in args]
    res = []

    while any(seqs):
        res.append(tuple((s.pop(0) if s else pad) for s in seqs))
    return res


print(mymapPad("abc", "123")) # [('a', '1'), ('b', '2'), ('c', '3')]
print(mymapPad("abc", "123456", pad=55)) # [('a', '1'), ('b', '2'), ('c', '3'), (55, '4'), (55, '5'), (55, '6')]

使用生成器(genators):yield


def myzip(*args):
    seqs = [list(s) for s in args]
    res = []
    while all(seqs):
        yield tuple(s.pop(0) for s in seqs)


print(list(myzip("anc", "123"))) # [('a', '1'), ('n', '2'), ('c', '3')]



def my_map_pad(*args, pad=None):
     seqs = [list(s) for s in args]
     res = []
     while any(seqs):
         yield tuple((s.pop(0) if s else pad) for s in seqs)



print(list(my_map_pad("abc", "123"))) # [('a', '1'), ('b', '2'), ('c', '3')]
print(list(my_map_pad("abc", "123456", pad=55))) # [('a', '1'), ('b', '2'), ('c', '3'), (55, '4'), (55, '5'), (55, '6')]


# 通过长度来设计
def myzip(*args):
    length = min(len(s) for s in args)
    return [tuple(s[i] for s in args)for i in range(length)]


print(myzip("abc", "123"))  # [('a', '1'), ('b', '2'), ('c', '3')]


def my_map_pad(*args, pad=None):
    length_max = max(len(s) for s in args)
    return [tuple((s[i] if len(s) > i else pad) for s in args) for i in range(length_max)]


print(list(myzip("anc", "123")))  # [('a', '1'), ('n', '2'), ('c', '3')]
print(list(my_map_pad("abc", "123")))  # [('a', '1'), ('b', '2'), ('c', '3')]
print(list(my_map_pad("abc", "123456", pad=55)))  # [('a', '1'), ('b', '2'), ('c', '3'), (55, '4'), (55, '5'), (55, '6')]

python3.0的解析语法

  • 对于集合,新的常量形式{1,2,3}等同于set([1,2,3]),并且新的集合解析语法{f(x) for x in s if p(x)} 就像是生成器表达式set(f(x) for x in s if p(x)),其中的f(x)是任意的表达式。
  • 对于字典,新的字典解析语法{key:val for (keym val) in zip(keys, vals)}像dict(zip(key, vals))形式一样的工作,并且{x:f(x) for x in items}像生成器表达式dict((x,f(x)) for x in items)一样工作。
>>> [x ** x for x in range(4)]
[1, 1, 4, 27]
>>> (x ** x for x in range(4))
<generator object <genexpr> at 0x0000026D53088620>
>>> {x ** x for x in range(4)}  # python3.0
{1, 27, 4}
>>> {x:x ** x for x in range(4)} # python3.0
{0: 1, 1: 1, 2: 4, 3: 27} 

集合和字典解析

#集合
>>> {x ** x for x in range(10)}
{256, 1, 46656, 16777216, 4, 387420489, 3125, 823543, 27}
>>> set({x ** x for x in range(10)})
{256, 1, 46656, 16777216, 4, 387420489, 3125, 823543, 27}
# 字典
>>> {x:x ** x for x in range(10)}
{0: 1, 1: 1, 2: 4, 3: 27, 4: 256, 5: 3125, 6: 46656, 7: 823543, 8: 16777216, 9: 387420489}
>>> dict((x,x**x) for x in range(10))
{0: 1, 1: 1, 2: 4, 3: 27, 4: 256, 5: 3125, 6: 46656, 7: 823543, 8: 16777216, 9: 387420489}

Python(一)

标签:rip   inter   偶数   运行   浅拷贝   布尔   quit   ppi   除法   

原文地址:https://www.cnblogs.com/yangchangjie/p/9916718.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!