基于Python实现层次性数据和闭包性质

目录
  • 绪论
  • 1.序列的表示
    • 表操作
    • 对链表的映射
  • 2.层次性结构
    • 对树的映射
  • 3.序列做为一种约定的界面

绪论

序对可以为我们提供用于构造复合数据的基本“粘接剂”,鉴于Python中tuple中元素不可变的性质,我们通过list来实现序对,如[1, 2]。Python的PyListObject对象中实际是存放的是PyObject*指针, 所以可以将PyListObject视为vecter<PyObject*>。这是一种盒子与指针表示方式(list内的元素表示为一个指向对象盒子的指针)。对于[1, 2],可将其视为以下结构:

我们不仅可以用[]去组合起各种数值,也可以用它取组合起其它序对。这样,序对就是一种通用的建筑砌块,通过它可以构造所有不同种类的数据结构来。比如想组合数值1, 2, 3, 4,我们可以用[[1, 2], [3, 4]]的方式(下图左),也可以用[[1, [2, 3]], 4](下图右)

可以构建元素本身也是序对的序对,这种能力称为[]闭包性质。注意,这里的闭包是来自抽象代数的术语(不是Python语法中那个闭包)。抽象代数中,如果将某个运算(操作)作用于某个集合的特定元素 ,产出的仍然是该集合的元素,则称该集合元素在该运算之下封闭。我们这里说组合数据对象的操作满足闭包性质,指通过它组合起数据对象得到的结果本身还可以通过同样的操作再进行组合。

闭包性质可以使我们构建层次性的结构,这种结构由一些部分构成,而其中的各个部分又是由它们的部分构成,并且可以继续下去。下面我们介绍用序对来表示序列

1.序列的表示

利用序对可以够造出的一类有用结构是序列——一批数据对象的有序汇集。利用序对表示序列的方式很多,一种最直接的表示方式为[1, [2, [3, [4, None]]]]如下图所示:

我们不妨将这种通过嵌套序对形成的序列称为链表。因为Python本身不内置链表结构,我们不妨用序对来实现链表:

class LinkedList():
    def __init__(self, *items) -> None:
        """提供两种初始化方式:序对或多个元素
        """
        if isinstance(items[0], list):
            self.pair = items[0]
        else:
            self.pair = self._construct(*items)

    def _construct(self, *items):
        """递归地构造链表
        """
        if items == ():
            return None
        else:
            item, *rest = items
            return [item, self._construct(*rest)]

    def __repr__(self):
        """重写打印函数
        """
        return "-->".join(map(str, self._flatten(self.pair)))

    def _flatten(self, pair):
        """遍历链表,返回其一维展开
        """
        if pair is None:
            return []
        else:
            return [pair[0]] + self._flatten(pair[1])

    @property
    def head(self):
        """获取链表头部元素
        """
        return self.pair[0]

    @property
    def rest(self):
        """获取链表头部元素之外的元素,并以链表形式返回
        """
        if self.pair[1] is None:
            return None
        else:
            return LinkedList(self.pair[1])

这样,我们就可以方便地构造链表并将其打印输出了:

print(LinkedList(1, 2, 3, 4))
# 1-->2-->3-->4

注意,None用于表示序对的链结束。在语言设计上可能有以下争论:None应该是个普通的名字吗?None应该算是一个普通的名字吗?None应该算是一个符号吗?他应该算是一个空表吗?在Python中,解决此问题的手段是将None的类型规定为<class 'NoneType'>

表操作

利用序对将元素的序列表示为链表之后,我们就可以使用常规的程序设计技术,通过获取链表的headrest的方式完成对链表的各种操作了。如下面的过程list-ref实际参数是一个表和一个数n,它返回这个表中的第n项:

def list_ref(items, n):
    if n == 0:
        return items.head
    else:
        return list_ref(items.rest, n-1)
print(list_ref(LinkedList(1, 4, 9, 16, 25), 3)) # 16

length过程则用于返回表中的项数:

def length(items):
    if items is None:
        return 0
    else:
        return 1 + length(items.rest)

print(length(LinkedList(1, 3, 5, 7))) # 4

或者写为迭代的形式(此处用尾递归的形式,即递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这样就无需保存返回值,可在常数空间内执行迭代型计算):

# 以迭代的方式计算lengths(尾递归)
def length(items):
    def length_iter(a, count):
        if a is None:
            return count
        else:
            return length_iter(a.rest, count + 1)
    return length_iter(items, 0)

print(length(LinkedList(1, 3, 5, 7))) # 4

当然, Python解释器默认是不开启尾递归优化的,需要用其他黑魔法实现,参考《Python开启尾递归优化!》

还有一种常见操作是append,如对odds[1, 3, 5, 7]squares:[1, 4, 9, 16, 25]append(odds, squares) 得[1 3 5 7 1 4 9 16 25]append(squares, odds)[1 4 9 16 25 1 3 5 7],也可以通过递归实现:

def append(lk_list1, lk_list2):
    if lk_list1 is None:
        return lk_list2.pair
    else:
        return [lk_list1.head, append(lk_list1.rest, lk_list2)]

odds = LinkedList(1, 3, 5, 7)
squares = LinkedList(1, 4, 9, 16, 25)
print(LinkedList(append(odds, squares))) # 1-->3-->5-->7-->1-->4-->9-->16-->25
print(LinkedList(append(squares, odds))) # 1-->4-->9-->16-->25-->1-->3-->5-->7

对链表的映射

另外一个特别拥有用的操作时将某种操作应用于一个链表的所有元素,得到所有结果构成的表。下面的过程将一个链表中的所有元素按给定因子做一次缩放:

def scale_list(items, factor):
    if items is None:
        return None
    else:
        return [items.head * factor, scale_list(items.rest, factor)]

print(LinkedList(scale_list(LinkedList(1, 2, 3, 4, 5), 10)))
# 10-->20-->30-->40-->50

我们可以抽象出这一具有一般性的想法,将其中的公共模式表述为一个高阶函数(接收其它函数做为参数)。

def my_map(proc, items):
    if items is None:
        return None
    else:
        return [proc(items.head), my_map(proc, items.rest)]

print(LinkedList(my_map(abs, LinkedList(-10, 2.5, -11.6, 17))))
# 10-->2.5-->11.6-->17
print(LinkedList(my_map(lambda x: x**2, LinkedList(1, 2, 3, 4, 5))))
# 1-->4-->9-->16-->25

这里的公共模式,其实就类似于设计模式中的模板方法,参见设计模式:模板方法。

现在我们可以用map给scale_list一个新定义:

def scale_list(items, factor):
    return LinkedList(my_map(lambda x: x*factor, items))

print(scale_list(LinkedList(1, 2, 3, 4, 5), 10))
# 10-->20-->30-->40-->50

map是一种很重要的结构,不仅因为它代表了一种公共模式,而且因为它建立起了一种处理表的高层抽象(与今日的Scala何其相似!),在老版本的scale_list中,程序的递归结构将人的注意力吸引到对表中元素的逐个处理中。通过map定义的scale_list抑制了这种细节层面上的情况,强调的是从元素表到结果表的一个缩放变换。这两种定义形式之间的差异,并不在于计算机会执行不同的计算过程(其实不会),而在于我们对同一个过程的不同思考方式。 从作用上看,map帮我们建起了一层抽象屏障,将实现表转换过程的实现,与与如何提取表中元素以及组合结果的细节隔离开。

2.层次性结构

注意,由于下面由于我们会涉及更复杂的数据结构,我们统一将序列就用Python内置的列表表示

我们下面来看元素本身也是序列的序列。比如我们可以认为[[1, 2], 3, 4]是将[1, 2]做为元素加入序列[3, 4]而得。这种表结构可以看做是树,即序列中的元素就是树的分支,而那些本身也是序列的元素就形成了树中的子树:

递归是处理树结构的一种很自然的工具,因为我们常常可以将对于树的操作归结为对它们的分支的操作,再将这种操作归结为对分支的分支的操作,如此下去,直至达到了树的叶子。如类似2.2.1中用length统计序列长度,我们通过以下代码统计树叶数目:

def count_leaves(tree):
    if not tree:
        return 0
    elif isinstance(tree, int):
        return 1
    else:
        return count_leaves(tree[0]) + count_leaves(tree[1:])
tree = [[1, 2], 3, 4]
print(count_leaves(tree)) # 4

对树的映射

map是处理序列的一种强有力抽象,与此类似,map与递归结合也是处理树的一种强有力抽象。类似于2.2.1中用scale_list过程对序列元素进行缩放,我们也可以设计scale_tree过程,该过程以一个因子和一棵叶子为数值的树作为参数,返回一颗具有同样形状的树,该树中的每个数值都乘以了这个因子:

def scale_tree(tree, factor):
    if not tree:
        return []
    if isinstance(tree, int):
        return tree * factor
    else:
        return [scale_tree(tree[0], factor)] + scale_tree(tree[1:], factor)

tree = [1, [2, [3, 4], 5], [6, 7]]
print(scale_tree(tree, 10))
# [10, [20, [30, 40], 50], [60, 70]]

实现scale_tree的另一种方法是将树看成子树的序列,并对它使用map。我们在这种序列上做映射,一次对各棵子树做缩放,并返回结果的表。对于基础情况,也就是当被处理的树是树叶时,就直接用因子去乘它:

def scale_tree(tree, factor):
    return list(map(lambda sub_tree: scale_tree(sub_tree, factor)
                    if isinstance(sub_tree, list)
                    else sub_tree * factor, tree))
tree = [1, [2, [3, 4], 5], [6, 7]]
print(scale_tree(tree, 10))
# [10, [20, [30, 40], 50], [60, 70]]

此处的map我们直接采用Python语言内置的map,当然也可以自己实现my_map,如下:

def my_map(proc, items):
    if items == []:
        return []
    else:
        return [proc(items[0])] + my_map(proc, items[1:])

3.序列做为一种约定的界面

数据抽象可以让我们设计出不被数据表示细节纠缠的程序,使程序保持很好的弹性。在这一节里,我们将要介绍与数据结构有关的另一种强有力的设计原理——使用约定的界面。

在1.3节中我们看到,通过实现为高阶过程的程序抽象,可以让我们抓住处理数值数据的一些程序模式。而在复合数据上工作做出类似的操作,则对我们操控数据结构的方式有着深刻的依赖性。如考虑一个与2.2.2节中的count_leaves类似的过程,它以一棵树为参数,计算出那些值为奇数的叶子的平方和:

def sum_odd_squares(tree):
    if not tree:
        return 0
    elif isinstance(tree, int):
        if tree % 2 == 1:
            return tree**2
        else:
            return 0
    else:
        return sum_odd_squares(tree[0]) + sum_odd_squares(tree[1:])

从表面上看,这一过程与下面的过程很不一样。下面的这个过程给定一个整数nn,对∀k⩽n∀k⩽n计算Fib(k)并筛选出其中为偶数的值,其中Fib(k)为第kk个Fibonacci数(设第0个Fibonacci数为0):

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

该过程表示如下:

def even_fibs(n):  # 枚举从0到n的整数
    def next(k):
        if k > n:
            return []
        else:
            f = fib(k)  # 对每个整数计算其fib
            if f % 2 == 0:  # 过滤结果,选出其中偶数
                return [f] + next(k + 1)  # 累积结果
            else:
                return next(k+1)
    return next(0)
print(even_fibs(5)) # [0, 2] (即[0 1 1 2 3 5]中的偶数为[0, 2])

虽然sum_odd_squares过程和even_fibs过程结构式差异非常大,但是对于两个计算的抽象描述却会揭露出它们间极大的相似性。sum_odd_squares过程:

  • 枚举出一棵树的树叶
  • 过滤它们,选出其中的奇数
  • 对选出的每一个数求平方
  • 用+累积起得到的结果

而 sum_odd_squares过程:

  • 枚举从00到nn的整数
  • 对每个整数计算相应的Fibonacci数
  • 过滤它们,选出其中的偶数
  • connect累计得到的结果

注意,connect函数用于对将两个数值对象连接为列表或将数值对象加入一个列表,定义如下:

def con(x, y):
    # y规定为int,x可以为int或list
    if isinstance(x, int):
        return [x] + [y]
    else:
        return x + [y]

信号工程师可能会发现,这种过程其实可以描述为信号流过一系列的级联处理步骤,每个步骤实现程序方案中的一部分。如下图所示:

遗憾的是,上面两个过程的定义并没有展现这种信号流结构。具体地说,我们的两个过程将enumerate工作散布在程序中各处,并将它与mapfilterreduce混在一起。如果我们能够重新组织这一程序,使信号流结构明显表现在写出的过程中,将会大大提高代码的清晰性。

其中mapfilterreduce算子可以采用Python内置函数,也可以自己实现。自己实现的话可以这样写:

def my_map(proc, sequence):
    if not sequence:
        return []
    else:
        return [proc(sequence[0])] + my_map(proc, sequence[1:])

print(my_map(lambda x: x**2, [1, 2, 3, 4, 5]))
# [1, 4, 9, 16, 25]

def my_filter(predicate, sequence):
    if not sequence:
        return []
    elif predicate(sequence[0]):
        return [sequence[0]] + my_filter(predicate, sequence[1:])
    else:
        return my_filter(predicate, sequence[1:])

print(my_filter(lambda x: x % 2, [1, 2, 3, 4, 5]))
# [1, 3, 5]

# print(list(accumulate([1,2,3])))

def my_reduce(op, sequence):
    if sequence[-1] and not sequence[:-1]:
        return sequence[-1]
    else:
        return op(my_reduce(op, sequence[:-1]), sequence[-1])

print(my_reduce(add, [1, 2, 3, 4, 5])) # 15
print(my_reduce(mul, [1, 2, 3, 4, 5])) # 120
print(my_reduce(con, [1, 2, 3, 4, 5])) # [1, 2, 3, 4, 5]

为了简便起见,我们下面mapfilterreduce算子统一采用Python内置函数。

除了这三个算子之外,我们还需要枚举(enumerate)出需要处理的数据序列。对于even-fibs,我们需要生成一个给定区间里的整数序列:

def enumerate_interval(low, high):
    if low > high:
        return []
    else:
        return [low] + enumerate_interval(low + 1, high)

print(enumerate_interval(2, 7)) # [2, 3, 4, 5, 6, 7]

对于sum_odd_squares,则需要枚举出一棵树的所有树叶:

# 枚举一棵树所有的树叶:
def enumerate_tree(tree):
    if not tree:
        return []
    elif isinstance(tree, int):
        return [tree]
    else:
        return enumerate_tree(tree[0]) + enumerate_tree(tree[1:])

print(enumerate_tree([1, [2, [3, 4], 5]])) # [1, 2, 3, 4, 5]

现在,我们就可以像上面的信号流图那样重新构造sum_odd_squareseven-fibs了。

sum_odd_squares的构造方法如下:

def sum_odd_squares(tree):
    return reduce(add,
                  map(lambda x: x**2,
                      filter(lambda x: x % 2,
                             enumerate_tree(tree))))

print(sum_odd_squares([1, 2, 3, 4, 5])) # 35

even-fibs的构造方法如下:

def even_fibs(n):
    return reduce(con,
                  filter(lambda x: not x % 2,
                         map(fib,
                             enumerate_interval(0, n))))

print(even_fibs(5)) #[0, 2]

将程序表示为一些针对序列的操作,这样做的价值就爱在于能帮助我们得到模块化的程序设计。而在工程设计中,模块化结构是控制复杂性的一种威力强大的策略。如同信号处理中设计者从标准的过滤器和变换装置中选出一些东西来级联,从而构造出各种系统。同样地,序列操作也形成了一个可以混合和匹配使用的标准程序元素库。

如我们在另一个产生前n+1n+1个Fibonacci数的平方的程序里,就可以使用取自过程sum_odd_squareseven-fibs的片段:

def list_fib_squares(n):
    return reduce(con,
                  map(lambda x: x**2,
                      map(fib,
                          enumerate_interval(0, n))))

print(list_fib_squares(5)) # [0, 1, 1, 4, 9, 25]

也可以重新安排有关的各个片段,将它们用在产生一个序列中所有奇数的平方之乘积的程序里:

def product_of_squares_of_odd_elements_sequence(sequence):
    return reduce(mul,
                  map(lambda x: x**2,
                      filter(lambda x: x % 2, sequence)))

print(product_of_squares_of_odd_elements_sequence([1, 2, 3, 4, 5])) # [0, 1, 1, 4, 9, 25]

我们同样可以采用序列操作的方式,重新去形式化各种常规的数据处理应用。假定有一个人事记录的序列,现在希望找出其中薪水最高的程序员的工资。假定有一个salary返回记录中的工资,谓词函数is_programmer检查某个记录是不是程序员,此时我们就可以写:

def salary_of_hightest_paid_programmer(records):
    return reduce(max,
                  map(salary,
                      filter(is_programmer, records)))

在这里,用表实现的序列被做为一种方便的界面,我们可以利用这种界面去组合起各种处理模块

到此这篇关于基于Python实现层次性数据和闭包性质的文章就介绍到这了,更多相关Python层次性数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python闭包技巧介绍

    目录 1.闭包:用函数代替类 2.访问定义在闭包的内的变量 1.闭包:用函数代替类 有时我们会定义只有一个方法(除了__init__()之外)的类,而这种类可以通过使用闭包(closure)来替代.闭包是被外层函数包围的内层函数,它能够获取外层函数范围中的变量(即使外层函数已执行完毕).因此闭包可以保存额外的变量环境,用于在函数调用时使用.考虑下面这个例子,这个类允许用户通过某种模板方案来获取URL. from urllib.request import urlopen class UrlTem

  • Python中的闭包

    目录 1.闭包概念 2.闭包条件 3.闭包完成计数效果 4.闭包的缺点及作用 1.闭包概念 闭包在函数中提出的概念,简单来说就是一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行.这样的一个函数我们称之为闭包.实际上闭包可以看做一种更加广义的函数概念.因为其已经不再是传统意义上定义的函数. 闭包这个概念不仅仅只有在Python中存在,在任何一个编程语言中都几乎存在. 2.闭包条件 闭包的条件: 外部函数中定义了内部函数 外部函数是有返回值 返回值是:内部函数 内部函数还引用

  • python闭包的实例详解

    1.在外部函数中定义内部函数,内部函数包含访问外部函数.即使外部函数的生命周期结束后,内部函数仍然可以访问外部函数变量. 2.外部函数的返回值是内部函数本身. 实例 def outer(): cheer = 'hello ' def inner(name): return cheer + name return inner if __name__ == "__main__": #输出hello kevin print(outer()('kevin')) 知识点扩展: 闭包的概念 我们尝

  • 关于Python中的闭包详解

    目录 1.闭包的概念 2.实现一个闭包 3.在闭包中外函数把临时变量绑定给内函数 4.闭包中内函数修改外函数局部变量 5.注意: 6.练习: 总结 1.闭包的概念 请大家跟我理解一下,如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数.闭包: 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用.这样就构成了一个闭包.一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失.但

  • Python函数对象与闭包介绍

    目录 一 函数对象 1.1 函数可以被引用 1.2 函数可以作为容器类型的元素 1.3 函数可以作为参数传入另外一个函数 1.4 函数的返回值可以是一个函数 二 闭包函数 2.1 闭与包 2.2 闭包的用途 一 函数对象 函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用 1.1 函数可以被引用 >>> def add(x,y): ... return x+y ... >>> func=add >>> func(1,2) 3 1.2

  • Python闭包的使用方法

    目录 1.闭包的定义和使用 2.闭包内函数修改外函数定义的变量(加nonlocal) 1.闭包的定义和使用 当返回的内部函数使用了外部函数的变量就形成了闭包闭包可以对外部函数的变量进行保存,还可以提高代码的可重用性 实现闭包的标准格式: 1.函数嵌套 2.内部函数使用外部函数的变量或参数 3.外部函数返回了内部函数 ''' 当返回的内部函数使用了外部函数的变量就形成了闭包 闭包可以对外部函数的变量进行保存,还可以提高代码的可重用性 实现闭包的标准格式:     1.函数嵌套     2.内部函数

  • 基于Python实现层次性数据和闭包性质

    目录 绪论 1.序列的表示 表操作 对链表的映射 2.层次性结构 对树的映射 3.序列做为一种约定的界面 绪论 序对可以为我们提供用于构造复合数据的基本“粘接剂”,鉴于Python中tuple中元素不可变的性质,我们通过list来实现序对,如[1, 2].Python的PyListObject对象中实际是存放的是PyObject*指针, 所以可以将PyListObject视为vecter<PyObject*>.这是一种盒子与指针表示方式(list内的元素表示为一个指向对象盒子的指针).对于[1

  • 基于Python的图像数据增强Data Augmentation解析

    1.1 简介 深层神经网络一般都需要大量的训练数据才能获得比较理想的结果.在数据量有限的情况下,可以通过数据增强(Data Augmentation)来增加训练样本的多样性, 提高模型鲁棒性,避免过拟合. 在计算机视觉中,典型的数据增强方法有翻转(Flip),旋转(Rotat ),缩放(Scale),随机裁剪或补零(Random Crop or Pad),色彩抖动(Color jittering),加噪声(Noise) 笔者在跟进视频及图像中的人体姿态检测和关键点追踪(Human Pose Es

  • 基于python实现模拟数据结构模型

    模拟栈 Stack() 创建一个空的新栈. 它不需要参数,并返回一个空栈. push(item)将一个新项添加到栈的顶部.它需要 item 做参数并不返回任何内容. pop() 从栈中删除顶部项.它不需要参数并返回 item .栈被修改. peek() 从栈返回顶部项,但不会删除它.不需要参数. 不修改栈. isEmpty() 测试栈是否为空.不需要参数,并返回布尔值. size() 返回栈中的 item 数量.不需要参数,并返回一个整数. class Stack(): def __init__

  • Python的净值数据接口调用示例分享

    代码描述:基于Python的净值数据接口调用代码实例 关联数据:净值数据 接口地址:https://www.juhe.cn/docs/api/id/25 #!/usr/bin/python # -*- coding: utf-8 -*- import json, urllib from urllib import urlencode #---------------------------------- # 净值数据调用示例代码 - 聚合数据 # 在线接口文档:http://www.juhe.c

  • 基于Python数据可视化利器Matplotlib,绘图入门篇,Pyplot详解

    Pyplot matplotlib.pyplot是一个命令型函数集合,它可以让我们像使用MATLAB一样使用matplotlib.pyplot中的每一个函数都会对画布图像作出相应的改变,如创建画布.在画布中创建一个绘图区.在绘图区上画几条线.给图像添加文字说明等.下面我们就通过实例代码来领略一下他的魅力. import matplotlib.pyplot as plt plt.plot([1,2,3,4]) plt.ylabel('some numbers') plt.show() 上图是我们通

  • Python基于dom操作xml数据的方法示例

    本文实例讲述了Python基于dom操作xml数据的方法.分享给大家供大家参考,具体如下: 1.xml的内容为del.xml,如下 <?xml version="1.0" encoding="utf-8"?> <catalog> <maxid>4</maxid> <login username="pytest" passwd='123456'> <caption>Python

  • 基于Python的Post请求数据爬取的方法详解

    为什么做这个 和同学聊天,他想爬取一个网站的post请求 观察 该网站的post请求参数有两种类型:(1)参数体放在了query中,即url拼接参数(2)body中要加入一个空的json对象,关于为什么要加入空的json对象,猜测原因为反爬虫.既有query参数又有空对象体的body参数是一件脑洞很大的事情. 一开始先在apizza网站 上了做了相关实验才发现上面这个规律的,并发现该网站的请求参数要为raw形式,要是直接写代码找规律不是一件容易的事情. 源码 import requests im

  • 基于Python对数据shape的常见操作详解

    这一阵在用python做DRL建模的时候,尤其是在配合使用tensorflow的时候,加上tensorflow是先搭框架再跑数据,所以调试起来很不方便,经常遇到输入数据或者中间数据shape的类型不统一,导致一些op老是报错.而且由于水平菜,所以一些常用的数据shape转换操作也经常百度了还是忘,所以想再整理一下. 一.数据的基本属性 求一组数据的长度 a = [1,2,3,4,5,6,7,8,9,10,11,12] print(len(a)) print(np.size(a)) 求一组数据的s

  • 基于Python实现一个简易的数据管理系统

    目录 创建mysql数据表 增删改查 启动应用  为了方便的实现记录数据.修改数据没有精力去做一个完整的系统去管理数据.因此,在python的控制台直接实现一个简易的数据管理系统,包括数据的增删改查等等.只需要在控制台层面调用相应的功能调用查询.修改等功能,这里记录一下实现过程. 创建mysql数据表 使用比较熟悉的数据库客户端来进行操作,这里使用的是navicate客户端来创建好相应的数据表. 创建数据库并指定编码字符集. CREATE DATABASE `data_boc` CHARACTE

  • 基于Python实现自动化生成数据报表

    目录 前言 开发工具 环境搭建 主要代码 前言 不要在用手敲生成Excel数据报表了,用Python自动生成Excel数据报表!废话不多说 让我们愉快地开始吧~ 开发工具 Python版本: 3.6.4 相关模块: pandasxlwingsmatplotlib模块: xlwingsmatplotlib模块: matplotlib模块: 以及一些Python自带的模块. 环境搭建 安装Python并添加到环境变量,pip安装需要的相关模块即可. 原始数据如下,主要有水果蔬菜名称.销售日期.销售数

随机推荐