add
parent
d58c40d3d6
commit
cbc4e335f7
|
@ -0,0 +1,14 @@
|
|||
在python中想用graphviz画图的时候,发现报了如下异常:
|
||||
|
||||
```
|
||||
RuntimeError: failed to execute ['dot', '-Tpdf', '-O', 'test'], make sure the Graphviz executables are on your systems' path
|
||||
```
|
||||
|
||||
很奇怪啊。python里面明明已经安装好了graphviz。。。
|
||||
经过google搜索,发现是系统也需要安装graphviz。。。
|
||||
|
||||
```
|
||||
sudo apt-get install graphviz
|
||||
```
|
||||
|
||||
系统安装graphviz完毕以后,代码就可以正常运行。
|
|
@ -0,0 +1,90 @@
|
|||
## 1.np.repeat VS np.tile
|
||||
repeat与tile函数都是复制相关的操作。
|
||||
tile操作,是复制的多维数组本身
|
||||
|
||||
```
|
||||
"""
|
||||
Construct an array by repeating A the number of times given by reps.
|
||||
“”“
|
||||
```
|
||||
|
||||
repeat操作复制的则是多维数组的每个元素
|
||||
|
||||
```
|
||||
"""
|
||||
Repeat elements of an array.
|
||||
"""
|
||||
```
|
||||
|
||||
## 2.np.repeat
|
||||
```
|
||||
>>> np.repeat(3, 4)
|
||||
array([3, 3, 3, 3])
|
||||
```
|
||||
|
||||
上面的操作得到一个长度为4的数组
|
||||
|
||||
```
|
||||
>>> x = np.array([[1,2],[3,4]])
|
||||
>>> np.repeat(x, 2)
|
||||
array([1, 1, 2, 2, 3, 3, 4, 4])
|
||||
```
|
||||
|
||||
上面先将高维的数组flatten至一维,然后进行复制。
|
||||
|
||||
```
|
||||
>>> np.repeat(x, 3, axis=1)
|
||||
array([[1, 1, 1, 2, 2, 2],
|
||||
[3, 3, 3, 4, 4, 4]])
|
||||
|
||||
```
|
||||
|
||||
axis=1是按行进行操作。
|
||||
|
||||
```
|
||||
>>> np.repeat(x, [1, 2], axis=0)
|
||||
array([[1, 2],
|
||||
[3, 4],
|
||||
[3, 4]])
|
||||
```
|
||||
|
||||
axis=0相当于按照行进行复制,并且前面的list [1,2]指定了按照不同的行复制不同的次数。
|
||||
|
||||
## 3.np.tile
|
||||
注意tile不需要指定axis
|
||||
```
|
||||
>>> a = np.array([0, 1, 2])
|
||||
>>> np.tile(a, 2)
|
||||
array([0, 1, 2, 0, 1, 2])
|
||||
```
|
||||
|
||||
```
|
||||
>>> np.tile(a, (2, 2))
|
||||
array([[0, 1, 2, 0, 1, 2],
|
||||
[0, 1, 2, 0, 1, 2]])
|
||||
>>> np.tile(a, (2, 1, 2))
|
||||
array([[[0, 1, 2, 0, 1, 2]],
|
||||
[[0, 1, 2, 0, 1, 2]]])
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
>>> b = np.array([[1, 2], [3, 4]])
|
||||
>>> np.tile(b, 2)
|
||||
array([[1, 2, 1, 2],
|
||||
[3, 4, 3, 4]])
|
||||
>>> np.tile(b, (2, 1))
|
||||
array([[1, 2],
|
||||
[3, 4],
|
||||
[1, 2],
|
||||
[3, 4]])
|
||||
```
|
||||
|
||||
```
|
||||
>>> c = np.array([1,2,3,4])
|
||||
>>> np.tile(c,(4,1))
|
||||
array([[1, 2, 3, 4],
|
||||
[1, 2, 3, 4],
|
||||
[1, 2, 3, 4],
|
||||
[1, 2, 3, 4]])
|
||||
```
|
|
@ -0,0 +1,186 @@
|
|||
## 1.java里get/set方法
|
||||
大部分的同学开始写java代码的时候,最初始的代码肯定是字段的get/set方法。大家对于java特别冗长的诟病,很大一部分来自于无处不在的get/set方法。甚至国内有相当一部分不负责任的java书籍,里面靠大段的get/set代码来拼凑篇幅。。。
|
||||
|
||||
来个最简单的例子,估计大家都写过类似的代码:
|
||||
|
||||
```
|
||||
public class Person {
|
||||
|
||||
private int age;
|
||||
|
||||
public Person(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2.python里的get/set方法
|
||||
python里如果按java的那一套写法,代码应该像是这样:
|
||||
|
||||
```
|
||||
class Person(object):
|
||||
|
||||
def __init__(self):
|
||||
self._age = None
|
||||
|
||||
def get_age(self):
|
||||
return self._age
|
||||
|
||||
def set_age(self,age):
|
||||
if(isinstance(age,str)):
|
||||
self._age = int(age)
|
||||
elif(isinstance(age,int)):
|
||||
self._age = age
|
||||
```
|
||||
|
||||
显然这是java风格的代码,python的哲学是简洁明了,这么麻烦的代码显然不是我们想要的。如果我们想直接访问上面Person类的age属性,也得使用get/set方法,否则会报错:
|
||||
|
||||
|
||||
```
|
||||
p = Person()
|
||||
p.set_age("18")
|
||||
print p.get_age() #OK,没问题
|
||||
print p.age #会报错,'Person' object has no attribute 'age'
|
||||
```
|
||||
|
||||
## 3.property方法
|
||||
如果我们想在py中直接访问属性,比如想在上面的例子中直接访问Person的age字段,可以在Person类的最后加如下一行代码:
|
||||
|
||||
```
|
||||
age = property(get_age,set_age)
|
||||
```
|
||||
|
||||
这样,我们就直接可以访问age字段了:
|
||||
|
||||
```
|
||||
p = Person()
|
||||
p.age = 18
|
||||
print p.get_age() #OK,没问题,返回的结果是18
|
||||
print p.age #OK,没问题,返回的结构也是18
|
||||
```
|
||||
|
||||
上面是用函数模式的方式来使用property的。当然我们也可以用装饰器的模式使用。
|
||||
|
||||
```
|
||||
class Person(object):
|
||||
|
||||
def __init__(self):
|
||||
self._age = None
|
||||
|
||||
@property
|
||||
def age(self):
|
||||
return self._age
|
||||
|
||||
@age.setter
|
||||
def age(self,age):
|
||||
if isinstance(age,str):
|
||||
self._age = int(age)
|
||||
elif isinstance(age,int):
|
||||
self._age = age
|
||||
|
||||
@age.deleter
|
||||
def age(self):
|
||||
del self._age
|
||||
|
||||
p = Person()
|
||||
p.age = "18"
|
||||
print p.age #18
|
||||
del p.age
|
||||
print p.age #报错,AttributeError: 'Person' object has no attribute '_age'
|
||||
```
|
||||
|
||||
上面使用property装饰器模式的时候注意几个小点:
|
||||
1.三个函数的名字与字段名是一样的。
|
||||
2.使用proterty可以比较简单实现字段的读写控制。例如想要字段为只读属性,那么只需要提供getter方法,上面的setter方法可以去掉。
|
||||
|
||||
## 4.用property定义需要计算的属性
|
||||
同时我们还可以用property来定义需要进行计算的字段。这些字段不会保存在对象中,只有当我们实际需要的时候才会完成真正计算。
|
||||
|
||||
```
|
||||
class Person(object):
|
||||
|
||||
def __init__(self):
|
||||
self._age = None
|
||||
|
||||
@property
|
||||
def age(self):
|
||||
return self._age
|
||||
|
||||
@age.setter
|
||||
def age(self,age):
|
||||
if isinstance(age,str):
|
||||
self._age = int(age)
|
||||
elif isinstance(age,int):
|
||||
self._age = age
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
return self.age * 10
|
||||
|
||||
p = Person()
|
||||
p.age = ("18")
|
||||
print p.height #180
|
||||
```
|
||||
|
||||
上面的例子,就是根据年龄来推算身高。。
|
||||
|
||||
## 5.property的基本原理
|
||||
在python中,property()是一个内置的函数。他的原型如下:
|
||||
|
||||
```
|
||||
def __init__(self, fget=None, fset=None, fdel=None, doc=None): # known special case of property.__init__
|
||||
"""
|
||||
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
|
||||
|
||||
fget is a function to be used for getting an attribute value, and likewise
|
||||
fset is a function for setting, and fdel a function for del'ing, an
|
||||
attribute. Typical use is to define a managed attribute x:
|
||||
|
||||
class C(object):
|
||||
def getx(self): return self._x
|
||||
def setx(self, value): self._x = value
|
||||
def delx(self): del self._x
|
||||
x = property(getx, setx, delx, "I'm the 'x' property.")
|
||||
|
||||
Decorators make defining new properties or modifying existing ones easy:
|
||||
|
||||
class C(object):
|
||||
@property
|
||||
def x(self):
|
||||
"I am the 'x' property."
|
||||
return self._x
|
||||
@x.setter
|
||||
def x(self, value):
|
||||
self._x = value
|
||||
@x.deleter
|
||||
def x(self):
|
||||
del self._x
|
||||
|
||||
# (copied from class doc)
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
在python的源码中,我们就很容易看出property的用法。其中,fget是一个获取字段值的函数,而fget是一个设置字段值的函数,fdel是一个删除属性的函数,doc是一个字符串(类似于注释)。从函数实现上看,这些函数参数都是可选的,默认为None,调用的其实就是__get__,__set__,__del__方法!
|
||||
|
||||
```
|
||||
age = property(get_age,set_age)
|
||||
```
|
||||
|
||||
这句代码,其实可以被分解为
|
||||
|
||||
```
|
||||
age = property()
|
||||
age = age.getter(get_age)
|
||||
age = age.setter(set_age)
|
||||
```
|
||||
|
||||
不去定义名字get_age和set_age,因为他们不是必须的,并且污染类的命名空间。而通过property的实现方式,都很简单。在python各种类库的源码中,经常会遇到很多类似的代码结构。
|
|
@ -0,0 +1,56 @@
|
|||
## 1.zip函数的定义
|
||||
zip是python中的一个内建函数,平时用得不是太多。zip的签名如下:
|
||||
|
||||
```
|
||||
def zip(seq1, seq2, *more_seqs): # known special case of zip
|
||||
"""
|
||||
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
|
||||
|
||||
Return a list of tuples, where each tuple contains the i-th element
|
||||
from each of the argument sequences. The returned list is truncated
|
||||
in length to the length of the shortest argument sequence.
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
从python源码中可以看出zip的大致用途:输入是n个序列,返回的是一个由tuples组成的list,每个tuple是输入序列中的第i个元素。如果输入的序列长度不一样,那么返回的列表将按输入序列中最短的那个做截断。
|
||||
|
||||
## 2.用法示范
|
||||
### 2.1 矩阵进行转置
|
||||
|
||||
```
|
||||
>>>a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
```
|
||||
|
||||
上述列表可以描述一个二维矩阵
|
||||
采用列表的方式,我们可以完成矩阵转置的需求
|
||||
|
||||
```
|
||||
>>> [ [row[col] for row in a] for col in range(len(a[0]))]
|
||||
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
|
||||
```
|
||||
|
||||
还可以通过zip的方式:
|
||||
|
||||
```
|
||||
>>> zip(*a)
|
||||
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
|
||||
```
|
||||
|
||||
上面的操作是利用*这个操作符,将list做unzip操作。
|
||||
因为列表里的类型是tuple,将tuple转换成list即可:
|
||||
|
||||
```
|
||||
>>> map(list, zip(*a))
|
||||
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
|
||||
```
|
||||
|
||||
### 2.2 生成字典
|
||||
|
||||
```
|
||||
>>> keys = [1, 2, 3]
|
||||
>>> values = ['a', 'b', 'c']
|
||||
>>> d = dict(zip(keys, values))
|
||||
>>> d
|
||||
{1: 'a', 2: 'b', 3: 'c'}
|
||||
```
|
|
@ -0,0 +1,100 @@
|
|||
在python中,经常会使用到type与isinstance两个内置的函数来判断变量属于什么类型。那么这两个函数有什么区别呢?下面来简单分析一下。
|
||||
|
||||
## 1.type
|
||||
type函数的源码如下:
|
||||
|
||||
```
|
||||
def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__
|
||||
"""
|
||||
type(object) -> the object's type
|
||||
type(name, bases, dict) -> a new type
|
||||
# (copied from class doc)
|
||||
"""
|
||||
pass
|
||||
```
|
||||
|
||||
此部分代码位于__builtin__.py中。从这段代码可以看出,type函数的用法很简单,就是type(object),返回的是传入的object的类型。
|
||||
|
||||
## 2.isinstance
|
||||
isinstance函数的源码:
|
||||
|
||||
```
|
||||
def isinstance(p_object, class_or_type_or_tuple): # real signature unknown; restored from __doc__
|
||||
"""
|
||||
isinstance(object, class-or-type-or-tuple) -> bool
|
||||
|
||||
Return whether an object is an instance of a class or of a subclass thereof.
|
||||
With a type as second argument, return whether that is the object's type.
|
||||
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
|
||||
isinstance(x, A) or isinstance(x, B) or ... (etc.).
|
||||
"""
|
||||
return False
|
||||
```
|
||||
|
||||
isinstance的用法为:
|
||||
|
||||
isinstance(object,type-or-tuple-or-class) -> bool
|
||||
传入的第一个参数为对象,第二个参数为类型名(int,str,float等)或者类型名的一个列表(如(str, str, int)为一个列表),返回值为一个布尔变量。
|
||||
|
||||
|
||||
## 3.两个函数的异同
|
||||
相同点
|
||||
都可以判断变量是否属于某个内建类型。
|
||||
|
||||
不同点
|
||||
1.type只接受一个参数,不仅可以判断变量是否属于某个类型,还可以直接返回参数类型。而isinstance只能判断是否属于某个已知的类型,不能直接得到变量所属的类型。
|
||||
|
||||
2.isinstance可以判断子类实例对象是属于父类的;而type会判断子类实例对象和父类类型不一样。
|
||||
|
||||
```
|
||||
class A1(object):
|
||||
pass
|
||||
|
||||
|
||||
class B1(A1):
|
||||
pass
|
||||
|
||||
|
||||
print type(A1()) is A1
|
||||
print type(B1()) is A1
|
||||
print isinstance(B1(), B1)
|
||||
```
|
||||
|
||||
输出结果为:
|
||||
|
||||
```
|
||||
True
|
||||
False
|
||||
True
|
||||
```
|
||||
|
||||
从以上的分析可以看出,type主要是用来获取未知变量的类型,而instance可以用于继承关系的判断
|
||||
|
||||
## 4.旧式类type
|
||||
旧式类与新式类的type()结果是不一样的。旧式类type的结果都为<type 'instance'>。
|
||||
|
||||
```
|
||||
class A1(object):
|
||||
pass
|
||||
|
||||
|
||||
class B1(A1):
|
||||
pass
|
||||
|
||||
|
||||
class C1:
|
||||
pass
|
||||
|
||||
|
||||
print type(B1())
|
||||
print type(C1())
|
||||
print type(C1()) is C1
|
||||
```
|
||||
|
||||
结果如下:
|
||||
|
||||
```
|
||||
<class '__main__.B1'>
|
||||
<type 'instance'>
|
||||
False
|
||||
```
|
|
@ -0,0 +1,168 @@
|
|||
## 1.前言
|
||||
虽然用python有一些年头了,但是在处理中文字符串的时候还是经常会遇到UnicodeEncodeError,UnicodeDecodeError等问题。每次都是随便调一调,程序能正常run以后就不管了。不巧今天又遇到了同样的状况,于是痛下决心,一定要把python中的字符编码问题搞清楚。
|
||||
|
||||
## 2.字节与字符
|
||||
计算机存储的任何数据,包括各种文本、图片、音视频文件等等,实际上都是一串二进制数字01字节序列组成的。相信大家都知道,一个字节Byte(B)是8个比特bit(b)。
|
||||
|
||||
而字符,自然就是符号了。比如说二十六个英文字母,阿拉伯数字,以及在python中最坑爹的汉字都是字符。python中遇到的字符编码问题,大部分都与汉字有关系。
|
||||
|
||||
写过java的小伙伴都知道,java中的IO模块,从大的方向来说,就可以分为字节流与字符流。字节流包括InputStream与OutputStream,字符流包括Writer与Reader。
|
||||
|
||||
有的同学会有疑问,为什么要搞这么复杂?统一用字节或者字符不就行了?
|
||||
|
||||
字节一般用来存储与网络传输,这样可以节省存储空间与网络传输带宽。而字符主要是用于显示,方便大家阅读。试想你正在debug,结果所有的输出是一堆01011100这种,那你还不得疯了。
|
||||
|
||||
## 3.编码(encoding)与解码(decoding)
|
||||
字符编码(Character encoding)、字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。常见的例子包括将拉丁字母表编码成摩斯电码和ASCII。其中,ASCII将字母、数字和其它符号编号,并用7比特的二进制来表示这个整数。通常会额外使用一个扩充的比特,以便于以1个字节的方式存储。(参考文献1)
|
||||
|
||||
encoding是将字符转换为字节,那么反过来将字节转换为字符则是decoding,两者是可逆的。编码主要是为了存储传输,而解码是为了方便阅读。
|
||||
|
||||
## 4.utf-8与unicode区别
|
||||
在正式讲python字符编码问题之前,还需要先扯清除unicode跟utf-8的关系。
|
||||
简单来说,unicode是一个字符集,而utf-8是一个编码规则,两者并不是同一维度的东西。
|
||||
字符集:为每一个字符分配一个唯一的 ID(学名为码位 / 码点 / Code Point)
|
||||
编码规则:将码位转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)
|
||||
|
||||
|
||||
## 4.python 2.7中的字符串
|
||||
python2x中的字符串实际有两种类型: str与unicode。很多时候出现的各种问题,就是出现在这上面。
|
||||
下面我们在python解释器中简单测试一下
|
||||
```
|
||||
>>> s = "你好"
|
||||
>>> s
|
||||
'\xe4\xbd\xa0\xe5\xa5\xbd'
|
||||
>>> type(s)
|
||||
<type 'str'>
|
||||
```
|
||||
上面的代码可以看出,s是str类型,在内部的存储方式就是一堆01二进制字节序列,显示出来是一串十六进制字符。
|
||||
很多时候我们看到定义字符串的时候会在前面加上一个前缀u,这个u其实就是表示这个字符串是unicode形式:
|
||||
|
||||
```
|
||||
>>> s = u"你好"
|
||||
>>> s
|
||||
u'\u4f60\u597d'
|
||||
>>> type(s)
|
||||
<type 'unicode'>
|
||||
```
|
||||
|
||||
我们看看编码的过程,大家记住编码是从字符->字节
|
||||
|
||||
```
|
||||
>>> s = u"你好"
|
||||
>>> s
|
||||
u'\u4f60\u597d'
|
||||
>>> type(s)
|
||||
<type 'unicode'>
|
||||
>>> s.encode('utf-8')
|
||||
'\xe4\xbd\xa0\xe5\xa5\xbd'
|
||||
```
|
||||
|
||||
再看看解码过程,解码自然就是从字节-> 字符
|
||||
|
||||
```
|
||||
>>> s = "你好"
|
||||
>>> s
|
||||
'\xe4\xbd\xa0\xe5\xa5\xbd'
|
||||
>>> type(s)
|
||||
<type 'str'>
|
||||
>>> s.decode("utf-8")
|
||||
u'\u4f60\u597d'
|
||||
```
|
||||
|
||||
## 5.UnicodeEncodeError
|
||||
既然是UnicodeEncodeError,那么应该是在字符->字节的环节出现了问题。来看下面的例子。
|
||||
|
||||
```
|
||||
def t1():
|
||||
f = open("ttt", "w")
|
||||
u1 = u'你好'
|
||||
f.writelines(u1 + "\n")
|
||||
|
||||
t1()
|
||||
```
|
||||
|
||||
运行这段代码以后,会有如下问题:
|
||||
|
||||
```
|
||||
TypeError: writelines() argument must be a sequence of strings
|
||||
```
|
||||
|
||||
这个问题比较好解释,writelines方法需要的是一个字符串序列,而u1是个unicode。
|
||||
将代码稍作修改
|
||||
|
||||
```
|
||||
def t1():
|
||||
f = open("ttt", "w")
|
||||
u1 = u'你好'
|
||||
f.write(u1)
|
||||
|
||||
t1()
|
||||
```
|
||||
|
||||
```
|
||||
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
|
||||
```
|
||||
|
||||
调用write方法时,如果传入的是字符串,就直接将该str写入文件,无需编码,因为str本身就是一堆二进制的01字节序列。
|
||||
如果是unicode,那需要先用encode方法将unicode字符串转换为二进制形式的str,才能保存。
|
||||
|
||||
重点来了,刚刚我们有提到,unicode -> str是encode过程。既然是encode,肯定需要指定encode的方法,比如最常用的utf-8。坑爹就在于,python2中如果不指定encode的形式,默认是用ASCII码来进行编码。
|
||||
很明显,ASCII只有128个拉丁字母,是木有处理中文字符能力的。所以报错里面的信息就是`ordinal not in range(128)`
|
||||
|
||||
解决方法很简单,将encode方式指定为utf-8即可。
|
||||
|
||||
```
|
||||
def t1():
|
||||
f = open("ttt", "w")
|
||||
u1 = u'你好'.encode("utf-8")
|
||||
f.write(u1)
|
||||
|
||||
t1()
|
||||
```
|
||||
|
||||
## 6.UnicodeDecodeError
|
||||
与UnicodeEncodeError对应的,UnicodeDecodeError肯定就是出现在字节->字符的环节。
|
||||
|
||||
```
|
||||
def t2():
|
||||
u1 = u"啦啦啦"
|
||||
print repr(u1)
|
||||
byte1 = u1.encode("utf-8")
|
||||
print repr(byte1)
|
||||
byte1.decode("gbk")
|
||||
|
||||
t2()
|
||||
```
|
||||
|
||||
```
|
||||
u'\u5566\u5566\u5566'
|
||||
'\xe5\x95\xa6\xe5\x95\xa6\xe5\x95\xa6'
|
||||
...
|
||||
UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 8: incomplete multibyte sequence
|
||||
```
|
||||
把一个经过 UTF-8编码后生成的字节序列 '\xe5\x95\xa6\xe5\x95\xa6\xe5\x95\xa6'用GBK解码成unicode的时候,因为GBK编码只有两字节,而UTF-8是三字节,多出来一个字节,肯定无法解析。因此,要防止出现UnicodeDecodeError,主要就是保持编码与解码的时候所用的编码方式一致。
|
||||
|
||||
## 7.coding:utf-8
|
||||
python代码在开头位置,一般都有这么一行:
|
||||
|
||||
```
|
||||
# -*- coding: utf-8
|
||||
```
|
||||
|
||||
作用是定义源代码的编码. 如果没有定义, 此源码中是不可以包含中文字符串的.
|
||||
|
||||
## 8.setdefaultencoding
|
||||
在源码中经常还可以看到如下代码:
|
||||
|
||||
```
|
||||
import sys
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf8')
|
||||
```
|
||||
上面几行代码的作用是设置默认的string的编码格式为utf8,在2.7以后已经不推荐使用这种方式了
|
||||
|
||||
|
||||
|
||||
|
||||
参考文献
|
||||
1.https://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81
|
|
@ -0,0 +1,164 @@
|
|||
## 1.Counter类
|
||||
Counter类是hashtable对象的计数,是dict的子类,从2.7以后的版本加入。
|
||||
计数器是我们常用的一个功能,collections中的Counter类就提供了此功能。
|
||||
|
||||
```
|
||||
>>> from collections import *
|
||||
>>> a = Counter()
|
||||
>>> b = Counter("aabbcccd")
|
||||
>>> c = Counter({"a":10,"b":20})
|
||||
>>> d = Counter(a=10,b=20)
|
||||
>>> b["a"]
|
||||
2
|
||||
>>> c.most_common()
|
||||
[('b', 20), ('a', 10)]
|
||||
```
|
||||
|
||||
## 2.defaultdict类
|
||||
defaultdict使用工厂函数创建字典,使用的时候不用考虑缺失的key。从2.5版本后引入。
|
||||
python原生的dict结构,如果使用d[key]的方式访问,需要先判断key是否存在。如果key在字典中不存在,会抛出一个KeyError的异常。
|
||||
defaultdict就是为解决这个痛点而生的。只要传入一个默认的工厂方法,如果用d[key]的方式访问字典而key不存在,会调用这个工厂方法使用其结果来作为这个key的默认值。
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
#coding:utf-8
|
||||
|
||||
from collections import *
|
||||
|
||||
def test_defaultdict():
|
||||
members = [
|
||||
['male', 'John'],
|
||||
['male', 'Jack'],
|
||||
['female', 'Lily'],
|
||||
['male', 'Pony'],
|
||||
['female', 'Lucy']
|
||||
]
|
||||
|
||||
result_dic = defaultdict(list)
|
||||
|
||||
for sex,name in members:
|
||||
result_dic[sex].append(name)
|
||||
|
||||
for k,v in result_dic.items():
|
||||
print k,"\t",v
|
||||
|
||||
test_defaultdict()
|
||||
```
|
||||
|
||||
最后的输出为:
|
||||
|
||||
```
|
||||
male ['John', 'Jack', 'Pony']
|
||||
female ['Lily', 'Lucy']
|
||||
```
|
||||
|
||||
## 3.OrderedDict类
|
||||
排序字典,是字典的子类。从2.7版本后引入。
|
||||
在python中,dict,set等数据结构的key是hash无序的。有时候,我们需要得到排序的字典。collections中的OrderedDict类即可满足我们的上述需求。
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
#coding:utf-8
|
||||
|
||||
from collections import *
|
||||
|
||||
def test_orderdict():
|
||||
raw_dic = {"watermelon":4,"grape":3,"apple":1,"mango":2}
|
||||
ret_dic_by_key = OrderedDict(sorted(raw_dic.items(),key = lambda item:item[0]))
|
||||
ret_dic_by_value = OrderedDict(sorted(raw_dic.items(),key = lambda item:item[1]))
|
||||
ret_dic_by_keylen = OrderedDict(sorted(raw_dic.items(),key = lambda item:len(item[0])))
|
||||
|
||||
print "ret_dic_by_key is: "
|
||||
for k,v in ret_dic_by_key.items():
|
||||
print k,"\t",v
|
||||
|
||||
print "ret_dic_by_value is: "
|
||||
for k,v in ret_dic_by_value.items():
|
||||
print k,"\t",v
|
||||
|
||||
print "ret_dic_by_keylen is: "
|
||||
for k,v in ret_dic_by_keylen.items():
|
||||
print k,"\t",v
|
||||
|
||||
test_orderdict()
|
||||
```
|
||||
|
||||
将代码run起来以后:
|
||||
|
||||
```
|
||||
ret_dic_by_key is:
|
||||
apple 1
|
||||
grape 3
|
||||
mango 2
|
||||
watermelon 4
|
||||
ret_dic_by_value is:
|
||||
apple 1
|
||||
mango 2
|
||||
grape 3
|
||||
watermelon 4
|
||||
ret_dic_by_keylen is:
|
||||
grape 3
|
||||
mango 2
|
||||
apple 1
|
||||
watermelon 4
|
||||
```
|
||||
|
||||
## 4.namedtuple
|
||||
namedtuple,命名元组,是一个工厂函数。从2.6版本后引入。
|
||||
namedtuple主要用来产生可以使用名称来访问元素的数据对象,通常用来增强代码的可读性, 在访问一些tuple类型的数据时尤其好用。
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
#coding:utf-8
|
||||
|
||||
from collections import *
|
||||
|
||||
def test_namedtuple():
|
||||
Point = namedtuple('Point','x y')
|
||||
location = [10,20]
|
||||
p = Point._make(location)
|
||||
print p
|
||||
print "p.x is: ",p.x
|
||||
print "p.y is: ",p.y
|
||||
|
||||
|
||||
test_namedtuple()
|
||||
```
|
||||
|
||||
将代码run起来以后:
|
||||
|
||||
```
|
||||
Point(x=10, y=20)
|
||||
p.x is: 10
|
||||
p.y is: 20
|
||||
```
|
||||
|
||||
## 5.deque
|
||||
deque,双端队列,从2.4版本后引入。
|
||||
双端队列(deque)是一种支持向两端高效地插入数据、支持随机访问的容器。它最大的好处就是实现了从队列 头部快速增加和取出对象: .popleft(), .appendleft() 。
|
||||
从piglei同志的博客中摘取一个deque的例子:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环
|
||||
的加载动画
|
||||
"""
|
||||
import sys
|
||||
import time
|
||||
from collections import deque
|
||||
|
||||
fancy_loading = deque('>--------------------')
|
||||
|
||||
while True:
|
||||
print '\r%s' % ''.join(fancy_loading),
|
||||
fancy_loading.rotate(1)
|
||||
sys.stdout.flush()
|
||||
time.sleep(0.08)
|
||||
|
||||
# Result:
|
||||
|
||||
# 一个无尽循环的跑马灯
|
||||
------------->-------
|
||||
```
|
|
@ -0,0 +1,63 @@
|
|||
## 1. 嵌套list
|
||||
python中嵌套的list还算比较常见的一种结构。比如我们经常用嵌套两层的list来模拟矩阵:
|
||||
|
||||
```
|
||||
>>> matrix = [[1,2,3],[4,5,6],[7,8,9]]
|
||||
>>> matrix
|
||||
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
```
|
||||
|
||||
很多时候我们想将这一个嵌套两层的list变成一个list,该怎么办呢?对于上面的例子,我们很容易找到如下的方式就可以满足需求:
|
||||
|
||||
```
|
||||
def flatmatrix(matrix):
|
||||
result = []
|
||||
for i in range(len(matrix)):
|
||||
result.extend(matrix[i])
|
||||
print result
|
||||
|
||||
|
||||
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||
flatmatrix(matrix)
|
||||
```
|
||||
|
||||
如果嵌套的list不是两层结构,而是任意的形式,上面的方式就不适用了。
|
||||
|
||||
## 2.递归打平嵌套list
|
||||
比较容易想到的是递归的方式处理任意形式的嵌套list。我们取遍历原始的list,如果里面的元素是list则递归,如果不是加入结果中,直到原始list的所有元素遍历结束。具体代码如下:
|
||||
|
||||
```
|
||||
def flat1(inputlist, result = None):
|
||||
if result is None:
|
||||
result = []
|
||||
for item in inputlist:
|
||||
if isinstance(item, list):
|
||||
flat1(item, result)
|
||||
else:
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
inputlist = ['it', 'is', ['a', ['test', 'of', ['circle', 'lists'], ','], 'please', 'like', ['it', 'and'], 'hello'], 'world']
|
||||
print flat1(inputlist)
|
||||
```
|
||||
|
||||
## 3.通过循环打平嵌套list
|
||||
一般来说,递归的优势是简洁明了,容易理解。缺点则是需要递归栈,效率比较低。我们尝试用非递归的方式来实现。
|
||||
|
||||
```
|
||||
def flat2(inputlist):
|
||||
result = []
|
||||
while inputlist:
|
||||
head = inputlist.pop(0)
|
||||
if isinstance(head, list):
|
||||
inputlist = head + inputlist
|
||||
else:
|
||||
result.append(head)
|
||||
return result
|
||||
|
||||
|
||||
inputlist = ['it', 'is', ['a', ['test', 'of', ['circle', 'lists'], ','], 'please', 'like', ['it', 'and'], 'hello'], 'world']
|
||||
print flat2(inputlist)
|
||||
```
|
||||
|
||||
循环的过程中,每次将输入list的首位元素取出来然后放到原来的位置,这样就起到了解开一层嵌套的作用,直到最后将所有的嵌套解开为止!
|
|
@ -0,0 +1,161 @@
|
|||
## 1.With语句是什么?
|
||||
有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。
|
||||
|
||||
如果不用with语句,代码如下:
|
||||
|
||||
```
|
||||
file = open("/tmp/foo.txt")
|
||||
data = file.read()
|
||||
file.close()
|
||||
```
|
||||
|
||||
这里有两个问题:
|
||||
|
||||
一是可能忘记关闭文件句柄;
|
||||
二是文件读取数据发生异常,没有进行任何处理。
|
||||
|
||||
下面是处理异常的加强版本:
|
||||
|
||||
```
|
||||
try:
|
||||
f = open('xxx')
|
||||
except:
|
||||
print 'fail to open'
|
||||
exit(-1)
|
||||
try:
|
||||
do something
|
||||
except:
|
||||
do something
|
||||
finally:
|
||||
f.close()
|
||||
```
|
||||
|
||||
虽然这段代码运行良好,但是太冗长了。
|
||||
|
||||
这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。
|
||||
|
||||
下面是with版本的代码:
|
||||
|
||||
```
|
||||
with open("/tmp/foo.txt") as file:
|
||||
data = file.read()
|
||||
```
|
||||
|
||||
## 2.with如何工作?
|
||||
紧跟with后面的语句被求值后,返回对象的 \__enter__() 方法被调用,这个方法的返回值将被赋值给as后面的变量。
|
||||
当with后面的代码块全部被执行完之后,将调用前面返回对象的 \__exit__()方法。
|
||||
|
||||
下面例子可以具体说明with如何工作:
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
# with_example01.py
|
||||
class Sample:
|
||||
def __enter__(self):
|
||||
print "In __enter__()"
|
||||
return "Foo"
|
||||
def __exit__(self, type, value, trace):
|
||||
print "In __exit__()"
|
||||
def get_sample():
|
||||
return Sample()
|
||||
with get_sample() as sample:
|
||||
print "sample:", sample
|
||||
```
|
||||
|
||||
运行代码,输出如下
|
||||
|
||||
```
|
||||
bash-3.2$ ./with_example01.py
|
||||
In __enter__()
|
||||
sample: Foo
|
||||
In __exit__()
|
||||
```
|
||||
|
||||
正如你看到的: 1. \__enter__()方法被执行 2. \__enter__()方法返回的值 - 这个例子中是”Foo”,赋值给变量’sample’ 3. 执行代码块,打印变量”sample”的值为 “Foo” 4. \__exit__()方法被调用
|
||||
|
||||
with真正强大之处是它可以处理异常。可能你已经注意到Sample类的 \__exit__ 方法有三个参数 val, type 和 trace。 这些参数在异常处理中相当有用。我们来改一下代码,看看具体如何工作的。
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
# with_example02.py
|
||||
class Sample:
|
||||
def __enter__(self):
|
||||
return self
|
||||
def __exit__(self, type, value, trace):
|
||||
print "type:", type
|
||||
print "value:", value
|
||||
print "trace:", trace
|
||||
def do_something(self):
|
||||
bar = 1/0
|
||||
return bar + 10
|
||||
with Sample() as sample:
|
||||
sample.do_something()
|
||||
```
|
||||
|
||||
这个例子中,with后面的get_sample()变成了Sample()。这没有任何关系,只要紧跟with后面的语句所返回的对象有 \__enter__() 和 \__exit__() 方法即可。此例中,Sample()的 \__enter__() 方法返回新创建的Sample对象,并赋值给变量sample。
|
||||
|
||||
代码执行后:
|
||||
|
||||
```
|
||||
bash-3.2$ ./with_example02.py
|
||||
type: <type 'exceptions.ZeroDivisionError'>
|
||||
value: integer division or modulo by zero
|
||||
trace: <traceback object at 0x1004a8128>
|
||||
Traceback (most recent call last):
|
||||
File "./with_example02.py", line 19, in <module>
|
||||
sample.do_something()
|
||||
File "./with_example02.py", line 15, in do_something
|
||||
bar = 1/0
|
||||
ZeroDivisionError: integer division or modulo by zero
|
||||
```
|
||||
|
||||
实际上,在with后面的代码块抛出任何异常时,\__exit__() 方法被执行。正如例子所示,异常抛出时,与之关联的type,value和stack trace传给 \__exit__() 方法,因此抛出的ZeroDivisionError异常被打印出来了。开发库时,清理资源,关闭文件等等操作,都可以放在 \__exit__ 方法当中。
|
||||
|
||||
另外,\__exit__ 除了用于tear things down,还可以进行异常的监控和处理,注意后几个参数。要跳过一个异常,只需要返回该函数True即可。
|
||||
|
||||
下面的样例代码跳过了所有的TypeError,而让其他异常正常抛出。
|
||||
|
||||
```
|
||||
def __exit__(self, type, value, traceback):
|
||||
return isinstance(value, TypeError)
|
||||
```
|
||||
|
||||
上文说了 \__exit__ 函数可以进行部分异常的处理,如果我们不在这个函数中处理异常,他会正常抛出,这时候我们可以这样写(python 2.7及以上版本,之前的版本参考使用contextlib.nested这个库函数):
|
||||
|
||||
```
|
||||
try:
|
||||
with open( "a.txt" ) as f :
|
||||
do something
|
||||
except xxxError:
|
||||
do something about exception
|
||||
```
|
||||
|
||||
总之,with-as表达式极大的简化了每次写finally的工作,这对保持代码的优雅性是有极大帮助的。
|
||||
|
||||
如果有多个项,我们可以这么写:
|
||||
|
||||
```
|
||||
with open("x.txt") as f1, open('xxx.txt') as f2:
|
||||
do something with f1,f2
|
||||
```
|
||||
|
||||
因此,Python的with语句是提供一个有效的机制,让代码更简练,同时在异常产生时,清理工作更简单。
|
||||
|
||||
## 3.相关术语
|
||||
要使用 with 语句,首先要明白上下文管理器这一概念。有了上下文管理器,with 语句才能工作。
|
||||
下面是一组与上下文管理器和with 语句有关的概念。
|
||||
上下文管理协议(Context Management Protocol):包含方法 \__enter__() 和 \__exit__(),支持该协议的对象要实现这两个方法。
|
||||
|
||||
上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了\__enter__() 和 \__exit__() 方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with 语句块上下文中的进入与退出操作。通常使用 with 语句调用上下文管理器,也可以通过直接调用其方法来使用。
|
||||
|
||||
运行时上下文(runtime context):由上下文管理器创建,通过上下文管理器的 \__enter__() 和\__exit__() 方法实现,\__enter__() 方法在语句体执行之前进入运行时上下文,\__exit__() 在语句体执行完后从运行时上下文退出。with 语句支持运行时上下文这一概念。
|
||||
|
||||
上下文表达式(Context Expression):with 语句中跟在关键字 with 之后的表达式,该表达式要返回一个上下文管理器对象。
|
||||
|
||||
语句体(with-body):with 语句包裹起来的代码块,在执行语句体之前会调用上下文管理器的 \__enter__() 方法,执行完语句体之后会执行\__exit__() 方法。
|
||||
|
||||
|
||||
|
||||
## 相关链接:
|
||||
1.http://blog.kissdata.com/2014/05/23/python-with.html
|
||||
2.https://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/
|
|
@ -0,0 +1,11 @@
|
|||
遇到一个形如$\alpha * e^{-29} = 0.1$的方程,求解$\alpha$的值。
|
||||
python中的sympy模块可以很轻松地解决这个问题。具体代码如下
|
||||
|
||||
```
|
||||
from sympy.abc import x, y, z, a, b
|
||||
from sympy import exp
|
||||
|
||||
print sympy.solve(exp(-1 * x * 29) - 0.1, x)
|
||||
```
|
||||
|
||||
求解可得$\alpha$的值为0.0793994859653119
|
|
@ -0,0 +1,226 @@
|
|||
## 1.最简单的绘制方式
|
||||
|
||||
绘制散点图是数据分析过程中的常见需求。python中最有名的画图工具是matplotlib,matplotlib中的scatter方法可以方便实现画散点图的需求。下面我们来绘制一个最简单的散点图。
|
||||
|
||||
数据格式如下:
|
||||
|
||||
```
|
||||
0 746403
|
||||
1 1263043
|
||||
2 982360
|
||||
3 1202602
|
||||
...
|
||||
```
|
||||
|
||||
其中第一列为X坐标,第二列为Y坐标。下面我们来画图。
|
||||
|
||||
```
|
||||
#!/usr/bin/env python
|
||||
#coding:utf-8
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def pltpicture():
|
||||
file = "xxx"
|
||||
xlist = []
|
||||
ylist = []
|
||||
with open(file, "r") as f:
|
||||
for line in f.readlines():
|
||||
lines = line.strip().split()
|
||||
if len(lines) != 2 or int(lines[1]) < 100000:
|
||||
continue
|
||||
x, y = int(lines[0]), int(lines[1])
|
||||
xlist.append(x)
|
||||
ylist.append(y)
|
||||
|
||||
plt.xlabel('X')
|
||||
plt.ylabel('Y')
|
||||
plt.scatter(xlist, ylist)
|
||||
plt.show()
|
||||
|
||||
```
|
||||
|
||||
|
||||
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/scatter/1.png)
|
||||
|
||||
## 2.更漂亮一些的画图方式
|
||||
上面的图片比较粗糙,是最简单的方式,没有任何相关的配置项。下面我们再用另外一份数据集画出更漂亮一点的图。
|
||||
数据集来自网络的公开数据集,数据格式如下:
|
||||
|
||||
```
|
||||
40920 8.326976 0.953952 3
|
||||
14488 7.153469 1.673904 2
|
||||
26052 1.441871 0.805124 1
|
||||
75136 13.147394 0.428964 1
|
||||
...
|
||||
```
|
||||
|
||||
第一列每年获得的飞行常客里程数;
|
||||
第二列玩视频游戏所耗时间百分比;
|
||||
第三列每周消费的冰淇淋公升数;
|
||||
第四列为label:
|
||||
1表示不喜欢的人
|
||||
2表示魅力一般的人
|
||||
3表示极具魅力的人
|
||||
|
||||
现在将每年获取的飞行里程数作为X坐标,玩视频游戏所消耗的事件百分比作为Y坐标,画出图。
|
||||
|
||||
```
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
file = "/home/mi/wanglei/data/datingTestSet2.txt"
|
||||
label1X, label1Y, label2X, label2Y, label3X, label3Y = [], [], [], [], [], []
|
||||
|
||||
with open(file, "r") as f:
|
||||
for line in f:
|
||||
lines = line.strip().split()
|
||||
if len(lines) != 4:
|
||||
continue
|
||||
distance, rate, label = lines[0], lines[1], lines[3]
|
||||
if label == "1":
|
||||
label1X.append(distance)
|
||||
label1Y.append(rate)
|
||||
|
||||
elif label == "2":
|
||||
label2X.append(distance)
|
||||
label2Y.append(rate)
|
||||
|
||||
elif label == "3":
|
||||
label3X.append(distance)
|
||||
label3Y.append(rate)
|
||||
|
||||
plt.figure(figsize=(8, 5), dpi=80)
|
||||
axes = plt.subplot(111)
|
||||
|
||||
label1 = axes.scatter(label1X, label1Y, s=20, c="red")
|
||||
label2 = axes.scatter(label2X, label2Y, s=40, c="green")
|
||||
label3 = axes.scatter(label3X, label3Y, s=50, c="blue")
|
||||
|
||||
plt.xlabel("every year fly distance")
|
||||
plt.ylabel("play video game rate")
|
||||
axes.legend((label1, label2, label3), ("don't like", "attraction common", "attraction perfect"), loc=2)
|
||||
|
||||
plt.show()
|
||||
```
|
||||
|
||||
最后效果图:
|
||||
![这里写图片描述](https://github.com/bitcarmanlee/easy-algorithm-interview-photo/blob/master/languages/python/scatter/2.png)
|
||||
|
||||
## 3.scatter函数详解
|
||||
我们来看看scatter函数的签名:
|
||||
|
||||
```
|
||||
def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
|
||||
vmin=None, vmax=None, alpha=None, linewidths=None,
|
||||
verts=None, edgecolors=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Make a scatter plot of `x` vs `y`
|
||||
|
||||
Marker size is scaled by `s` and marker color is mapped to `c`
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x, y : array_like, shape (n, )
|
||||
Input data
|
||||
|
||||
s : scalar or array_like, shape (n, ), optional
|
||||
size in points^2. Default is `rcParams['lines.markersize'] ** 2`.
|
||||
|
||||
c : color, sequence, or sequence of color, optional, default: 'b'
|
||||
`c` can be a single color format string, or a sequence of color
|
||||
specifications of length `N`, or a sequence of `N` numbers to be
|
||||
mapped to colors using the `cmap` and `norm` specified via kwargs
|
||||
(see below). Note that `c` should not be a single numeric RGB or
|
||||
RGBA sequence because that is indistinguishable from an array of
|
||||
values to be colormapped. `c` can be a 2-D array in which the
|
||||
rows are RGB or RGBA, however, including the case of a single
|
||||
row to specify the same color for all points.
|
||||
|
||||
marker : `~matplotlib.markers.MarkerStyle`, optional, default: 'o'
|
||||
See `~matplotlib.markers` for more information on the different
|
||||
styles of markers scatter supports. `marker` can be either
|
||||
an instance of the class or the text shorthand for a particular
|
||||
marker.
|
||||
|
||||
cmap : `~matplotlib.colors.Colormap`, optional, default: None
|
||||
A `~matplotlib.colors.Colormap` instance or registered name.
|
||||
`cmap` is only used if `c` is an array of floats. If None,
|
||||
defaults to rc `image.cmap`.
|
||||
|
||||
norm : `~matplotlib.colors.Normalize`, optional, default: None
|
||||
A `~matplotlib.colors.Normalize` instance is used to scale
|
||||
luminance data to 0, 1. `norm` is only used if `c` is an array of
|
||||
floats. If `None`, use the default :func:`normalize`.
|
||||
|
||||
vmin, vmax : scalar, optional, default: None
|
||||
`vmin` and `vmax` are used in conjunction with `norm` to normalize
|
||||
luminance data. If either are `None`, the min and max of the
|
||||
color array is used. Note if you pass a `norm` instance, your
|
||||
settings for `vmin` and `vmax` will be ignored.
|
||||
|
||||
alpha : scalar, optional, default: None
|
||||
The alpha blending value, between 0 (transparent) and 1 (opaque)
|
||||
|
||||
linewidths : scalar or array_like, optional, default: None
|
||||
If None, defaults to (lines.linewidth,).
|
||||
|
||||
verts : sequence of (x, y), optional
|
||||
If `marker` is None, these vertices will be used to
|
||||
construct the marker. The center of the marker is located
|
||||
at (0,0) in normalized units. The overall marker is rescaled
|
||||
by ``s``.
|
||||
|
||||
edgecolors : color or sequence of color, optional, default: None
|
||||
If None, defaults to 'face'
|
||||
|
||||
If 'face', the edge color will always be the same as
|
||||
the face color.
|
||||
|
||||
If it is 'none', the patch boundary will not
|
||||
be drawn.
|
||||
|
||||
For non-filled markers, the `edgecolors` kwarg
|
||||
is ignored and forced to 'face' internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
paths : `~matplotlib.collections.PathCollection`
|
||||
|
||||
Other parameters
|
||||
----------------
|
||||
kwargs : `~matplotlib.collections.Collection` properties
|
||||
|
||||
See Also
|
||||
--------
|
||||
plot : to plot scatter plots when markers are identical in size and
|
||||
color
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
* The `plot` function will be faster for scatterplots where markers
|
||||
don't vary in size or color.
|
||||
|
||||
* Any or all of `x`, `y`, `s`, and `c` may be masked arrays, in which
|
||||
case all masks will be combined and only unmasked points will be
|
||||
plotted.
|
||||
|
||||
Fundamentally, scatter works with 1-D arrays; `x`, `y`, `s`, and `c`
|
||||
may be input as 2-D arrays, but within scatter they will be
|
||||
flattened. The exception is `c`, which will be flattened only if its
|
||||
size matches the size of `x` and `y`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
.. plot:: mpl_examples/shapes_and_collections/scatter_demo.py
|
||||
|
||||
"""
|
||||
```
|
||||
|
||||
其中具体的参数含义如下:
|
||||
|
||||
x,y是相同长度的数组。
|
||||
s可以是标量,或者与x,y长度相同的数组,表明散点的大小。默认为20。
|
||||
c即color,表示点的颜色。
|
||||
marker 是散点的形状。
|
Loading…
Reference in New Issue