Python API快餐教程(1) - 字符串查找API

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python API快餐教程(1) - 字符串查找API相关的知识,希望对你有一定的参考价值。

参考技术A 字符串是7种序列类型中的一种。
除了序列的操作函数,比如len()来求字符串长度之外,Python还为字符串提供丰富到可以写个编辑器的API.

首先,下面的查找API都是为了查找位置,或者查一共有几次这样的操作。
如果只是想判断一个字符串是不是另一个字符串的子串的话,使用序列的in运算符就可以了。
例:

原型:str.count(sub[, start[, end]])

字符串的count函数可以数出来有多少次匹配,我们看个例子,有5个ha和3个hei

输出为5和2.
haha只能匹配两次。

再加上扩展参数:

find函数的行为是,如果能找到,则返回在序列中的坐标,如果找不到,则返回-1. rfind是从右向左查找。我们来看例子:

输出值为0和6.

找不到的例子:

输出值都是-1.

完整形式:

index和rindex的功能与find和rfind基本上一致,除了在找不到时会抛出ValueError异常而不是返回-1.

例:

所以我们需要加try...except语句来处理之:

有时候,我们希望做从头匹配或者匹配尾部。这时候就要用到startswith函数和endswith函数。例:

这两个返回值均为True.

如果需要更复杂的匹配,还是需要正则表达式。与Java等语言不同,Python中的正则表达式有专门的模块,字符串的API不负责这个事情。

JavaClojure快餐教程-运行在JVM上的Lisp方言

Clojure快餐教程(1) - 运行在JVM上的Lisp方言

Java作为目前为止被使用最广泛的使用虚拟机的编程语言,带动了JVM上语言族的繁荣。
有根红苗正的为JVM设计的动态语言Groovy,目前最主要被用于Gradle编译环境中;也有Jython, JRuby等动态语言在JVM上的实现,也有scala这样强大的混合语言。
在这之中,clojure是比较特殊的一种,它是Lisp语言在JVM上的一种方言。

使用clojure调用java

首先我们先看一下如何用clojure来调用java的方法。
有了这个利器之后,我们就获得了整个java世界的类库的强大支持。

首先我们看个例子,做个最简单的两个大整数的乘法。用Java写是这样风格的:

import java.math.BigInteger;public class Test {    public static void test(){
        BigInteger bi1 = new BigInteger("1234567890");
        BigInteger bi2 = new BigInteger("9876543210");
        System.out.println(bi1.multiply(bi2));
    }
}

用Clojure写起来,一开始可能会有点不适应,会是这样的:

(ns .test2)
(import java.math.BigInteger)

(println (.multiply (new BigInteger "1234567890") (new BigInteger "9876543210")))

这里可能会给代码补全带来一点困难,因为在写.multiply时,还不知道它是应用在哪个对象或者类上。但是Clojure就是这种风格了,函数名、运算符先行。

Clojure对于Lisp的改进

Clojure作为运行在JVM上的Lisp方言,第一个优势就是可以无缝调用Java API。另外,针对Lisp括号多的问题,Clojure除了S表达式中常用的()之外,增加了[]{}两种括号。

()表示列表,[]表示向量,{}用于表示哈希表。
另外,#{}用来表示集合。

user=> (class [])clojure.lang.PersistentVectoruser=> (class ())clojure.lang.PersistentList$EmptyListuser=> (class {})clojure.lang.PersistentArrayMapuser=> (class #{})clojure.lang.PersistentHashSet

在Clojure中生存

查看帮助 - clojure.repl/doc

doc宏用于查看常量、特殊表、函数或者宏的文档。在以后的编程中我们会经常使用它。

例:

user=> (doc doc) -------------------------clojure.repl/doc
([name])
Macro  Prints documentation for a var or special form given its name

列表

在Lisp中,列表数据和代码的表示形式一样,都是S表达式。S表达式可以通俗理解为一个括号括起来的,以第一个符号进行求值的表达式。
所以,如果要避免一个列表被求值,我们有两种办法:

  1. 用list函数来生成列表

  2. 用quota特殊表来避免被求值

例:

user=> (list 1 2 3)(1 2 3)user=> (doc list)-------------------------
clojure.core/list
([& items])
  Creates a new list containing the items.
niluser=> (quote (2 3 4))(2 3 4)user=> (doc quote)-------------------------
quote
  (quote form)
Special Form
  Yields the unevaluated form.

  Please see http://clojure.org/special_forms#quote
niluser=> '(3 4 5)(3 4 5)

"'"符号是quote的简写形式。

列表操作

lisp中最常用的car和cdr在clojure中不被支持,当然更不用想caddr之类的了。

如果要取表头,需要使用first函数,例:

user=> (first (list 2 3 4))2

相对地,取除了表头之外的部分,使用rest函数,例:

user=> (rest (list 2 3 4))(3 4)

如果取最后一个元素,可以使用last函数获取最后一个元素,例:

user=> (last '(5 6 7))7

一般地,我们如果想取第n个下标的元素的话,可以使用nth函数:

user=> (nth (list 8 9 10) 2)10

虽然没有car和cdr,但是将fist和rest连接在一起的cons函数还是有的:

user=> (cons 1 '(2 3 4))
(1 2 3 4)

向量

向量有点类似于数组,对于随机访问元素进行优化。clojure使用中括号来表示向量。
由于不是用的S表达式,所以也就不用quote了。
first, last, nth和rest函数对于向量仍然适用。

user=> (first [1 2 3 4])1user=> (nth [4 5 6 7] 3)7user=> (rest [3 4 5 6])(4 5 6)

但是请注意rest返回的并不是一个向量,而且一个序列类型。
我们可以用class函数来看一下具体的类型:

user=> (class (rest '(1 2 3)))clojure.lang.PersistentListuser=> (class (rest [1 2 3]))clojure.lang.PersistentVector$ChunkedSeq

哈希表

用完了小括号和中括号,下面是大括号出场的时候了。没错,大括号用来表示哈希表。例:

{:name "hello", :age 18}

访问使用键的名字为函数名来获取值,例:

user=> (:name {:name "Hello", :age 18})"Hello"

集合

小中大括号都用完了肿么办,只好在大括号之前加个"#"来表示。例:

user=> #{ 1 2 3}
#{1 3 2}

集合中的元素不能重复。如果要构建一个set,可以使用sorted-set函数。

user=> (sorted-set 1 2 2 3)
#{1 2 3}

变量绑定

使用def特殊表可以将值绑定到一个全局变量上。
前面学习的数据结构,现在都可以用来绑定到变量上了。
def可以多次绑定,以最新绑定的值为准。例:

user=> (def a '(1 2 3))#'user/a

定义函数

作为Lisp的一种方言,函数是一定在生存阶段要学懂的必备技能。

我们使用fn特殊表来定义函数,如果作为函数对象,或者叫做lambda表达式,可以不定义名字。

比如,我们定义一个求平方的匿名函数:

user=> (fn [i] (* i i))#object[user$eval17$fn__18 0x7f284218 "user$eval17$fn__18@7f284218"]

函数没有什么特殊的,也可以用def绑定到一个变量上,这就是我们通常定义函数的写法:

user=> (def sqr (fn [i] (* i i)))#'user/sqruser=> (sqr 4)16

我们也可以使用defn宏来定义函数:

user=> (defn sqr3 [i] (* i i i))#'user/sqr3user=> (sqr3 4)64

通过defn宏,还可以为函数提供说明文档,然后文档就可以通过doc函数来看了。例:

user=> (defn succ "return next x" [x] (+ x 1))#'user/succuser=> (doc succ)-------------------------
user/succ
([x])
  return next x
nil

小结

  • Clojure是一门运行在JVM上的Lisp方言。与Lisp还是有一些不同,比如使用[],{},#{}来表示向量、哈希表和集合。比如不支持car, cdr, setq等。

  • Clojure支持通过import宏来引用java包

  • Clojure通过new特殊表可以创建java对象

  • clojure.core/doc函数用来查看帮助文档

  • def特殊表用于绑定变量

  • fn特殊表用于定义函数,主要用于定义匿名函数

  • defn宏可以定义函数的说明文档


阅读全文请点击下面的阅读原文

以上是关于Python API快餐教程(1) - 字符串查找API的主要内容,如果未能解决你的问题,请参考以下文章

云栖社区 Tensorflow快餐教程

Clojure快餐教程-运行在JVM上的Lisp方言

JavaClojure快餐教程-运行在JVM上的Lisp方言

使用提供程序和快餐栏查找已停用小部件的祖先是不安全的

PyTorch快餐教程2019 - Multi-Head Attention

代码补全快餐教程 - 预训练模型的加载和使用