Python复习(持续更新)

最近在看机器学习相关的东西,Python有点生疏了,简单复习一下。
(*号表示有待补充)
参加来源:Learn X in Y minutes、菜鸟教程

文章目录

  • 1 基础变量类型、操作符
    • 1.1 字符串
      • 字符串的基本操作
      • 字符串的格式操作
    • 1.2 None
    • 1.3 输入输出
  • 2 Python 常用容器
    • 2.1 List
      • list的切片操作
    • 2.2 tuple 元组*
    • 2.3 dict 字典
    • 2.4 set
  • 3 控制流
    • 3.1 判断语句
    • 3.2 循环
    • 3.3 异常*
    • 3.4 with操作*
  • 4 迭代*
    • 4.1 可迭代对象
  • 5 函数*
    • 5.1 定义
    • 5.2 参数
    • 5.3 返回值*
    • 5.4 全局变量
  • 6 类*
    • 6.1 类的基础用法
    • 6.2 继承*
    • 6.3 多继承
  • 7 其他*
    • 7.1 生成器*
    • 7.2 装饰器*

1 基础变量类型、操作符

在Python3中要注意“/”和“//”的区别,“/”是正常除,“//”是取整除
Python复习(持续更新)_第1张图片
Python支持乘方运算
Python复习(持续更新)_第2张图片
Python中的逻辑运算用首字母大写的TrueFalse表示真和假(底层还是1和0)。用and表示与操作,or表示或操作,not表示非操作。而不是C++或者是Java当中的&&, || 和!。
优先级:not > and > or

1.1 字符串

字符串的基本操作

python的字符串支持+拼接操作,单引号和双引号都表示字符串

# Strings are created with " or '
"This is a string."
'This is also a string.'

# Strings can be added too! But try not to do this.
"Hello " + "world!"  # => "Hello world!"

用len()来计算字符串长度,也可以使用[]来访问单个字符

# A string can be treated like a list of characters
"This is a string"[0]  # => 'T'

# You can find the length of a string
len("This is a string")  # => 16

字符串的格式操作

Python3.6以后支持格式操作(f后面不可以用空格!)
Python复习(持续更新)_第3张图片

1.2 None

在Python中None也是一个对象,所有的None都指向同一个对象

# None is an object
None  # => None

# Don't use the equality "==" symbol to compare objects to None
# Use "is" instead. This checks for equality of object identity.
"etc" is None  # => False
None is None   # => True

如果要判断一个值为空,可以用**bool()**函数,只要是空值都会返回False

# None, 0, and empty strings/lists/dicts/tuples all evaluate to False.
# All other values are True
bool(None)# => False
bool(0)   # => False
bool("")  # => False
bool([])  # => False
bool({})  # => False
bool(())  # => False

1.3 输入输出

输出是print,输入用input,在input()中传入字符串参数,会被当做提示输出:
在这里插入图片描述

2 Python 常用容器

2.1 List

a = [1, 2, 3, 4]  # Point a at a new list, [1, 2, 3, 4]
b = a             # Point b at what a is pointing to
b is a            # => True, a and b refer to the same object
b == a            # => True, a's and b's objects are equal
b = [1, 2, 3, 4]  # Point b at a new list, [1, 2, 3, 4]
b is a            # => False, a and b do not refer to the same object
b == a            # => True, a's and b's objects are equal

在list末尾插入删除元素

# Add stuff to the end of a list with append
li.append(1)    # li is now [1]
li.append(2)    # li is now [1, 2]
li.append(4)    # li is now [1, 2, 4]
li.append(3)    # li is now [1, 2, 4, 3]
# Remove from the end with pop
li.pop()        # => 3 and li is now [1, 2, 4]
# Let's put it back
li.append(3)    # li is now [1, 2, 4, 3] again.

删除中间的元素可以用del或者remove()

# Remove arbitrary elements from a list with "del"
del li[2]  # li is now [1, 2, 3]

# Remove first occurrence of a value
li.remove(2)  # li is now [1, 3]
li.remove(2)  # Raises a ValueError as 2 is not in the list

插入元素用insert()

# Insert an element at a specific index
li.insert(1, 2)  # li is now [1, 2, 3] again

如果要将两个list合并,可以用**+或者extend()**

li + other_li  # => [1, 2, 3, 4, 5, 6]

# Concatenate lists with "extend()"
li.extend(other_li)  # Now li is [1, 2, 3, 4, 5, 6]

判断元素第一次出现的位置用index(),要判断list中是否包含某个元素,用in关键字

li.index(2)  # => 1
li.index(4)  # Raises a ValueError as 4 is not in the list

# Check for existence in a list with "in"
1 in li  # => True

list的切片操作

要注意list的切片操作是左闭右开的区间,如果要获得逆序可以使第三个参数为-1

# You can look at ranges with slice syntax.
# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
li[1:3]   # Return list from index 1 to 3 => [2, 4]
li[2:]    # Return list starting from index 2 => [4, 3]
li[:3]    # Return list from beginning until index 3  => [1, 2, 4]
li[::2]   # Return list selecting every second entry => [1, 4]
li[::-1]  # Return list in reverse order => [3, 4, 2, 1]
# Use any combination of these to make advanced slices
# li[start:end:step]

2.2 tuple 元组*

tuple 和 list 不同的是,前者使用 () 进行初始化,且tuple是不可变的(但是tuple中的可变元素依旧可变,如list)

# Tuples are like lists but are immutable.
tup = (1, 2, 3)
tup[0]      # => 1
tup[0] = 3  # Raises a TypeError

大部分list的操作,tuple也支持,如 len()、+、切片、in

2.3 dict 字典

dict的作用和map类似,存储key和value的键值对,用 {} 表示dict

# Dictionaries store mappings from keys to values
empty_dict = {}
# Here is a prefilled dictionary
filled_dict = {"one": 1, "two": 2, "three": 3}

两种获取value 的方法

# Look up values with []
filled_dict["one"]  # => 1
filled_dict.get('one') #=> 1

如果要获取所有key或是value的list,可以用如下方法,但注意在python3.7以前顺序和插入顺序是不同的

list(filled_dict.keys())  # => ["three", "two", "one"] in Python <3.7
list(filled_dict.keys())  # => ["one", "two", "three"] in Python 3.7+

list(filled_dict.values())  # => [3, 2, 1]  in Python <3.7
list(filled_dict.values())  # => [1, 2, 3] in Python 3.7+

用setdefault() 方法来插入不存在的键值对,用update() 方法来更新值

filled_dict.setdefault("five", 5)  # filled_dict["five"] is set to 5
filled_dict.setdefault("five", 6)  # filled_dict["five"] is still 5

# Adding to a dictionary
filled_dict.update({"four":4})  # => {"one": 1, "two": 2, "three": 3, "four": 4}
filled_dict["four"] = 4         # another way to add to dict

如果要删除,可以使用del

dict4 = {'name': 'Tom', 'age': 18}
del dict4['name']  # 删除字典,如果键不存在,返回错误
print(dict4)
del dict4  # 删除整个字典
print(dict4)

(关于dict的删除有四种方法,详见Python字典删除键值对和元素的四种方法)

2.4 set

set和c++中的一样,都是用来存储不重复元素的容器。set中的元素是不可变对象,这意味着 list 是不可以传入set中。

# Sets store ... well sets
empty_set = set()
# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
some_set = {1, 1, 2, 2, 3, 4}  # some_set is now {1, 2, 3, 4}

调用add() 方法添加元素
set支持交叉并补

 Do set intersection with &
# 计算交集
other_set = {3, 4, 5, 6}
filled_set & other_set  # => {3, 4, 5}

# Do set union with |
# 计算并集
filled_set | other_set  # => {1, 2, 3, 4, 5, 6}

# Do set difference with -
# 计算差集
{1, 2, 3, 4} - {2, 3, 5}  # => {1, 4}

# Do set symmetric difference with ^
# 去掉交集
{1, 2, 3, 4} ^ {2, 3, 5}  # => {1, 4, 5}

超集和子集的判断

# Check if set on the left is a superset of set on the right
{1, 2} >= {1, 2, 3} # => False

# Check if set on the left is a subset of set on the right
{1, 2} <= {1, 2, 3} # => True

超集和子集的概念

set 同样支持 in 、copy()等操作

3 控制流

3.1 判断语句

Python中不支持switch语句!!!
Python中的else if 是 elif,如:

a = 1
if a > 1:
	print("a>1")
elif a == 0:
	print("a==0")
else:
	print("a<0")

3.2 循环

for animal in ["dog", "cat", "mouse"]:
    # You can use format() to interpolate formatted strings
    print("{} is a mammal".format(animal))

for i in range(4):
    print(i)
# prints:0 1 2 3

for i in range(4, 8):
    print(i)
# prints:4 5 6 7 

for i in range(4, 8, 2):
    print(i)
# prints:4 6 

使用enumerate函数,同时迭代list的下标和元素:

"""
To loop over a list, and retrieve both the index and the value of each item in the list
prints:
    0 dog
    1 cat
    2 mouse
"""
animals = ["dog", "cat", "mouse"]
for i, value in enumerate(animals):
    print(i, value)

while 和C++类似

x = 0
while x < 4:
    print(x)
    x += 1  # Shorthand for x = x + 1

3.3 异常*

3.4 with操作*

4 迭代*

4.1 可迭代对象

可迭代对象的使用

filled_dict = {"one": 1, "two": 2, "three": 3}
our_iterable = filled_dict.keys()
print(our_iterable)  # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface.

# We can loop over it.
for i in our_iterable:
    print(i)  # Prints one, two, three

可迭代对象不能使用[]来访问元素,但可以使用next关键字来获取下一元素。使用iter() 方法可以将可迭代对象转换成迭代器,也可以使用**list()**将其转换成列表:

# However we cannot address elements by index.
our_iterable[1]  # Raises a TypeError

# An iterable is an object that knows how to create an iterator.
our_iterator = iter(our_iterable)

# Our iterator is an object that can remember the state as we traverse through it.
# We get the next object with "next()".
next(our_iterator)  # => "one"

# It maintains state as we iterate.
next(our_iterator)  # => "two"
next(our_iterator)  # => "three"

# After the iterator has returned all of its data, it raises a StopIteration exception
next(our_iterator)  # Raises StopIteration

# We can also loop over it, in fact, "for" does this implicitly!
our_iterator = iter(our_iterable)
for i in our_iterator:
    print(i)  # Prints one, two, three

# You can grab all the elements of an iterable or iterator by calling list() on it.
list(our_iterable)  # => Returns ["one", "two", "three"]
list(our_iterator)  # => Returns [] because state is saved

5 函数*

5.1 定义

使用def 定义函数

# Use "def" to create new functions
def add(x, y):
    print("x is {} and y is {}".format(x, y))
    return x + y  # Return values with a return statement

# Calling functions with parameters
add(5, 6)  # => prints out "x is 5 and y is 6" and returns 11

# Another way to call functions is with keyword arguments
add(y=6, x=5)  # Keyword arguments can arrive in any order.

5.2 参数

也可以在参数名之前加上*表示任意长度的参数,参数会被转化成list:

# You can define functions that take a variable number of
# positional arguments
def varargs(*args):
    return args

varargs(1, 2, 3)  # => (1, 2, 3)

如果在参数前加上**表示接受一个dict

# You can define functions that take a variable number of
# keyword arguments, as well
def keyword_args(**kwargs):
    return kwargs

# Let's call it to see what happens
keyword_args(big="foot", loch="ness")  # => {"big": "foot", "loch": "ness"}


# You can do both at once, if you like
def all_the_args(*args, **kwargs):
    print(args)
    print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) prints:
    (1, 2)
    {"a": 3, "b": 4}
"""

5.3 返回值*

python是支持返回多个值的:

# Returning multiple values (with tuple assignments)
def swap(x, y):
    return y, x  # Return multiple values as a tuple without the parenthesis.
                 # (Note: parenthesis have been excluded but can be included)

x = 1
y = 2
x, y = swap(x, y)     # => x = 2, y = 1
# (x, y) = swap(x,y)  # Again parenthesis have been excluded but can be included.

python也可以返回一个函数,它支持函数式编程

# Python has first class functions
def create_adder(x):
    def adder(y):
        return x + y
    return adder

add_10 = create_adder(10)
add_10(3)   # => 13

5.4 全局变量

在函数中使用和全局变量同名的变量不会造成覆盖,若要使用全局变量,需加上global 关键字

# Function Scope
x = 5

def set_x(num):
    # Local var x not the same as global variable x
    x = num    # => 43
    print(x)   # => 43

def set_global_x(num):
    global x
    print(x)   # => 5
    x = num    # global var x is now set to 6
    print(x)   # => 6

set_x(43)
set_global_x(6)

6 类*

6.1 类的基础用法

一个完整的类:

class Human:
    # 类属性,可以直接通过Human.species调用,而不需要通过实例
    species = "H. sapiens"

    # 最基础的构造函数
    # 加了下划线的函数和变量表示不应该被用户使用,其中双下划线的函数或者是变量将不会被子类覆盖
    # 前后都有双下划线的函数和属性是类当中的特殊属性
    def __init__(self, name):
        # Assign the argument to the instance's name attribute
        self.name = name

        # Initialize property
        self._age = 0
        
    # 类中的函数,所有实例可以调用,第一个参数必须是self
    # self表示实例的引用
    def say(self, msg):
        print("{name}: {message}".format(name=self.name, message=msg))

    # Another instance method
    def sing(self):
        return 'yo... yo... microphone check... one two... one two...'
        
    @classmethod
    # 加上了注解,表示是类函数
    # 通过Human.get_species来调用,所有实例共享
    def get_species(cls):
        return cls.species

    @staticmethod
    # 静态函数,通过类名或者是实例都可以调用
    def grunt():
        return "*grunt*"

    @property
    # property注解,类似于get,set方法
    # 效率很低,除非必要,不要使用
    def age(self):
        return self._age

    # This allows the property to be set
    @age.setter
    def age(self, age):
        self._age = age

    # This allows the property to be deleted
    @age.deleter
    def age(self):
        del self._age

类的使用

# 这个是main函数也是整个程序入口的惯用写法
if __name__ == '__main__':
    # 实例化一个类,获取类的对象
    i = Human(name="Ian")
    # 执行say方法
    i.say("hi")                     # "Ian: hi"
    j = Human("Joel")
    j.say("hello")                  # "Joel: hello"
    # i和j都是Human的实例,都称作是Human类的对象
    
    # 类属性被所有实例共享,一旦修改全部生效
    i.say(i.get_species())          # "Ian: H. sapiens"
    Human.species = "H. neanderthalensis"
    i.say(i.get_species())          # => "Ian: H. neanderthalensis"
    j.say(j.get_species())          # => "Joel: H. neanderthalensis"

    # 通过类名调用静态方法
    print(Human.grunt())            # => "*grunt*"

    # 不能通过对象调用静态方法,因为对象会传入self实例,会导致不匹配
    print(i.grunt())                # => TypeError: grunt() takes 0 positional arguments but 1 was given

    # 实例级别的属性是独立的,各个对象各自拥有,修改不会影响其他对象内的值
    i.age = 42
    # Get the property
    i.say(i.age)                    # => "Ian: 42"
    j.say(j.age)                    # => "Joel: 0"
    # Delete the property
    del i.age
    # i.age                         # => this would raise an AttributeError

6.2 继承*

一般将不同的类放在不同的文件当中,import引入再实现继承

from human import Human


# Specify the parent class(es) as parameters to the class definition
class Superhero(Human):

    # If the child class should inherit all of the parent's definitions without
    # any modifications, you can just use the "pass" keyword (and nothing else)
    # but in this case it is commented out to allow for a unique child class:
    # pass
    # 如果要完全继承父类的所有的实现,我们可以使用关键字pass,表示跳过。这样不会修改父类当中的实现

    # Child classes can override their parents' attributes
    species = 'Superhuman'

    # 子类会完全继承父类的构造方法,也可以进行改造,比如额外增加一些参数
    def __init__(self, name, movie=False,
                 superpowers=["super strength", "bulletproofing"]):

        # 额外新增的参数
        self.fictional = True
        self.movie = movie
        # be aware of mutable default values, since defaults are shared
        self.superpowers = superpowers

        # The "super" function lets you access the parent class's methods
        # that are overridden by the child, in this case, the __init__ method.
        # This calls the parent class constructor:
        # 子类可以通过super关键字调用父类的方法
        super().__init__(name)

    # override the sing method
    # 重写父类的sing方法
    def sing(self):
        return 'Dun, dun, DUN!'

    # add an additional instance method
    # 新增方法,只属于子类
    def boast(self):
        for power in self.superpowers:
            print("I wield the power of {pow}!".format(pow=power))

if __name__ == '__main__':
    sup = Superhero(name="Tick")

    # Instance type checks
    # 检查继承关系
    if isinstance(sup, Human):
        print('I am human')
    # 检查类型
    if type(sup) is Superhero:
        print('I am a superhero')

    # Get the Method Resolution search Order used by both getattr() and super()
    # This attribute is dynamic and can be updated
    # 查看方法查询的顺序
    # 先是自身,然后沿着继承顺序往上,最后到object
    print(Superhero.__mro__)    # => (,
                                # => , )

    # 相同的属性子类覆盖了父类
    # Calls parent method but uses its own class attribute
    print(sup.get_species())    # => Superhuman

    # Calls overridden method
    # 相同的方法也覆盖了父类
    print(sup.sing())           # => Dun, dun, DUN!

    # Calls method from Human
    # 继承了父类的方法
    sup.say('Spoon')            # => Tick: Spoon

    # Call method that exists only in Superhero
    # 子类特有的方法
    sup.boast()                 # => I wield the power of super strength!
                                # => I wield the power of bulletproofing!

    # Inherited class attribute
    sup.age = 31
    print(sup.age)              # => 31

    # Attribute that only exists within Superhero
    print('Am I Oscar eligible? ' + str(sup.movie))

6.3 多继承

python是支持多继承的,比如可以创建一个叫Batman的类,同时继承Superhero 和 Bat:

# And yet another class definition that inherits from Superhero and Bat
# superhero.py
from superhero import Superhero
from bat import Bat

# Define Batman as a child that inherits from both Superhero and Bat
class Batman(Superhero, Bat):

    def __init__(self, *args, **kwargs):
        # Typically to inherit attributes you have to call super:
        # super(Batman, self).__init__(*args, **kwargs)      
        # However we are dealing with multiple inheritance here, and super()
        # only works with the next base class in the MRO list.
        # So instead we explicitly call __init__ for all ancestors.
        # The use of *args and **kwargs allows for a clean way to pass arguments,
        # with each parent "peeling a layer of the onion".
        # 通过类名调用两个父类各自的构造方法
        Superhero.__init__(self, 'anonymous', movie=True, 
                           superpowers=['Wealthy'], *args, **kwargs)
        Bat.__init__(self, *args, can_fly=False, **kwargs)
        # override the value for the name attribute
        self.name = 'Sad Affleck'

    # 重写父类的sing方法
    def sing(self):
        return 'nan nan nan nan nan batman!'

执行这个类:

if __name__ == '__main__':
    sup = Batman()

    # Get the Method Resolution search Order used by both getattr() and super().
    # This attribute is dynamic and can be updated
    # 可以看到方法查询的顺序是先沿着superhero这条线到human,然后才是bat
    print(Batman.__mro__)       # => (, 
                                # => , 
                                # => , 
                                # => , )

    # Calls parent method but uses its own class attribute
    # 只有superhero有get_species方法
    print(sup.get_species())    # => Superhuman

    # Calls overridden method
    print(sup.sing())           # => nan nan nan nan nan batman!

    # Calls method from Human, because inheritance order matters
    sup.say('I agree')          # => Sad Affleck: I agree

    # Call method that exists only in 2nd ancestor
    # 调用蝙蝠类的声呐方法
    print(sup.sonar())          # => ))) ... (((

    # Inherited class attribute
    sup.age = 100
    print(sup.age)              # => 100

    # Inherited attribute from 2nd ancestor whose default value was overridden.
    print('Can I fly? ' + str(sup.fly)) # => Can I fly? False

7 其他*

7.1 生成器*

使用yield 关键字创建生成器,每次调用的时候执行到yield 关键字处则停止,下次再调用还是从此处开始往下执行

# Generators help you make lazy code.
def double_numbers(iterable):
    for i in iterable:
        yield i + i

# Generators are memory-efficient because they only load the data needed to
# process the next value in the iterable. This allows them to perform
# operations on otherwise prohibitively large value ranges.
# NOTE: `range` replaces `xrange` in Python 3.
for i in double_numbers(range(1, 900000000)):  # `range` is a generator.
    print(i)
    if i >= 30:
        break

还可以使用() 来生成生成器

# Just as you can create a list comprehension, you can create generator
# comprehensions as well.
values = (-x for x in [1,2,3,4,5])
for x in values:
    print(x)  # prints -1 -2 -3 -4 -5 to console/terminal

# You can also cast a generator comprehension directly to a list.
values = (-x for x in [1,2,3,4,5])
gen_to_list = list(values)
print(gen_to_list)  # => [-1, -2, -3, -4, -5]

7.2 装饰器*

引入functools当中的wraps之后,可以创建一个装饰器。装饰器可以在不修改函数内部代码的前提下,在外面包装一层其他的逻辑:

# Decorators
# In this example `beg` wraps `say`. If say_please is True then it
# will change the returned message.
from functools import wraps


def beg(target_function):
    @wraps(target_function)
    # 如果please为True,额外输出一句Please! I am poor :(
    def wrapper(*args, **kwargs):
        msg, say_please = target_function(*args, **kwargs)
        if say_please:
            return "{} {}".format(msg, "Please! I am poor :(")
        return msg

    return wrapper


@beg
def say(say_please=False):
    msg = "Can you buy me a beer?"
    return msg, say_please


print(say())                 # Can you buy me a beer?
print(say(say_please=True))  # Can you buy me a beer? Please! I am poor :(

你可能感兴趣的:(机器学习,python)