分类: Python技术

Python技术

Python解释器和IPython

Python解释器和IPython

简介
今天给大家介绍一下Python的一个功能非常强大的解释器IPython。虽然Python本身自带解释器,但是相对而言IPython的功能更加的强大。

Python解释器
Python是自带解释器的,我们在命令行输入python即可进入python的解释器环境:

$> python
Python 2.7.15 (default, Oct 2 2018, 11:47:18)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.2)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.
>>> site = “www.flydean.com”
>>> site
‘www.flydean.com’
>>>

python解释器的提示符是>>>。

python提供了一个非常有用的命令help,我们可以使用help来查看要使用的命令。

>>> help
Type help() for interactive help, or help(object) for help about object.

在Python3中,还提供了tab的补全功能:

>>> site
‘www.flydean.com’
>>> site.
site.capitalize( site.expandtabs( site.isalpha( site.isprintable( site.lower( site.rindex( site.splitlines( site.upper(
site.casefold( site.find( site.isdecimal( site.isspace( site.lstrip( site.rjust( site.startswith( site.zfill(
site.center( site.format( site.isdigit( site.istitle( site.maketrans( site.rpartition( site.strip(
site.count( site.format_map( site.isidentifier( site.isupper( site.partition( site.rsplit( site.swapcase(
site.encode( site.index( site.islower( site.join( site.replace( site.rstrip( site.title(
site.endswith( site.isalnum( site.isnumeric( site.ljust( site.rfind( site.split( site.translate(

使用起来非常的方便。

和Python自带的解释器之外,还有一个更加强大的解释器叫做IPython。我们一起来看看。

IPython
IPython是一个非常强大的解释器,通常它是和jupyter notebook一起使用的。在IPython3.X中,IPython和Jupyter是作为一个整体一起发布的。但是在IPython4.X之后,Jupyter已经作为一个单独的项目,从IPython中分离出来了。

使用IPython很简单,输入IPython命令即可:

$> ipython
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33)
Type ‘copyright’, ‘credits’ or ‘license’ for more information
IPython 6.2.1 — An enhanced Interactive Python. Type ‘?’ for help.

In [1]: site= “www.flydean.com”

In [2]: site
Out[2]: ‘www.flydean.com’

IPython的提示符是In [1]:

基本上Python自带的命令在IPython中都是可以使用的。

IPython提供了4个非常有用的命令:

command description
? Introduction and overview of IPython’s features.
%quickref Quick reference.
help Python’s own help system.
object? Details about ‘object’, use ‘object??’ for extra details.
魔法函数
IPython中有两种魔法函数,一种是Line magics,一种是Cell magics。

Line magics 接收本行的输入作为函数的输入,是以%开头的。而Cell magics可以接收多行的数据,直到你输入空白回车为止。是以%%开头的。

比如我们想要看一个timeit的魔法函数的用法,可以使用Object?来表示:

$> In [4]: %timeit?
Docstring:
Time execution of a Python statement or expression

Usage, in line mode:
%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
or in cell mode:
%%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
code
code…

timeit用来统计程序的执行时间,我们分别看下Line magics和Cell magics的使用:

In [4]: %timeit?

In [5]: %timeit range(1000)
199 ns ± 3.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [6]: %%timeit range(1000)
…: range(1000)
…:
208 ns ± 12.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

事实上,如果只是LIne magics的话,我们可以省略前面的%,但是对于Cell magics来说,是不能省略的。

In [7]: timeit range(1000)

200 ns ± 4.03 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

常见的魔法函数有下面几种:

代码相关的: %run, %edit, %save, %macro, %recall, etc.
shell环境相关的: %colors, %xmode, %automagic, etc.
其他的函数: %reset, %timeit, %%writefile, %load, or %paste.
运行和编辑
使用%run 可以方便的运行外部的python脚本。

In [8]: run?
Docstring:
Run the named file inside IPython as a program.

Usage::

%run [-n -i -e -G]
[( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
( -m mod | file ) [args]

run有几个非常有用的参数,比如-t 可以用来统计程序的时间。-d可以进行调试环境,-p可以进行profiler分析。

使用%edit 可以编辑多行代码,在退出之后,IPython将会执行他们。

如果不想立即执行的话,可以加上-x参数。

Debug
可以使用%debug 或者 %pdb 来进入IPython的调试环境:

In [11]: debug
> /Users/flydean/.pyenv/versions/anaconda3-5.1.0/lib/python3.6/site-packages/IPython/core/compilerop.py(99)ast_parse()
97 Arguments are exactly the same as ast.parse (in the standard library),
98 and are passed to the built-in compile function.”””
—> 99 return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
100
101 def reset_compiler_flags(self):

ipdb>

In [12]: pdb
Automatic pdb calling has been turned ON

In [13]: pdb
Automatic pdb calling has been turned OFF

或者可以使用 %run -d theprogram.py 来调试一个外部程序。

History
IPython可以存储你的输入数据和程序的输出数据,IPython的一个非常重要的功能就是可以获取到历史的数据。

在交互环境中,一个简单的遍历历史输入命令的方式就是使用up- 和 down- 箭头。

更强大的是,IPython将所有的输入和输出都保存在In 和 Out这两个变量中,比如In[4]。

In [1]: site = “www.flydean.com”

In [2]: site
Out[2]: ‘www.flydean.com’

In [3]: In
Out[3]: [”, ‘site = “www.flydean.com”‘, ‘site’, ‘In’]

可以使用 _ih[n]来访问特定的input:

In [4]: _ih[2]
Out[4]: ‘site’

_i, _ii, _iii 可以分别表示前一个,前前一个和前前前一个输入。

除此之外,全局变量 _i 也可以用来访问输入,也就是说:

_i<n> == _ih[<n>] == In[<n>]
_i14 == _ih[14] == In[14]

同样的,对于输出来说也存在着三种访问方式:

_<n> == _oh[<n>] == Out[<n>]
_12 == Out[12] == _oh[12]

*后的三个输出也可以通过 _, __ 和 ___来获取。

还可以使用%history来列出之前的历史数据进行选择。

history可以和 %edit,%rerun,%recall,%macro,%save和%pastebin 配和使用:

通过传入数字,可以选择历史的输入行号。

%pastebin 3 18-20

上面的例子会选择第3行和第18-20行输入。

运行系统命令
使用!可以直接运行系统命令:

In [27]: !pwd
/Users/flydean/Downloads

还可以用变量接收运行的结果,比如 : files = !ls

数字字符串和列表

Python基础之:数字字符串和列表

简介
Python的主要应用是进行科学计算,科学计算的基础就是数字,字符串和列表。本文将会详细的给大家介绍一下这三个数据类型的使用情况。

数字
数字是任何科学计算中非常中要的类型,在Python中*常见的数字类型就是int和float。

看几个基本的数字操作:

In [8]: 1+1
Out[8]: 2

In [9]: 3*2 + 10
Out[9]: 16

In [10]: (65 + 23) / 4
Out[10]: 22.0

上面我们可以看到,没有小数的是int类型,带有小数的是float类型。

除法运算 (/) 永远返回浮点数类型。如果要做 floor division得到一个整数结果(忽略小数部分)你可以使用 // 运算符;如果要计算余数,可以使用 %

In [11]: 54 / 4
Out[11]: 13.5

In [12]: 54 // 4
Out[12]: 13

In [13]: 54 % 4
Out[13]: 2

** 可以表示乘方运算:

In [14]: 4 ** 3
Out[14]: 64
我们可以将数字的运算赋值给特定的变量,并且可以使用该变量进行后续的运算。

In [15]: a = 12

In [16]: b = 14

In [17]: a * b
Out[17]: 168

在交互式环境中,_表示上一个输出:

In [17]: a * b
Out[17]: 168

In [18]: 100 + _
Out[18]: 268

除了int和float,Python还支持其他的数据类型,比如Decimal和Fraction,甚至还支持复数。

字符串
Python中字符串有三种表示形式,可以使用单引号,双引号和三引号来表示。

In [19]: site1 = ‘www.flydean.com’

In [20]: site2= “www.flydean.com”

In [21]: site3= “””www.flydean.com”””
三引号主要用于跨行输出,字符串中的回车换行会自动包含到字符串中,如果不想包含,在行尾添加一个 \ 即可。如下:

print(“””\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
“””)

如果需要转义的话,可以使用反斜杠 \

In [22]: site4 = “www.\”flydean\”.com”

In [23]: site4
Out[23]: ‘www.”flydean”.com’

如果你不希望前置了 \ 的字符转义成特殊字符,可以使用 原始字符串 方式,在引号前添加 r 即可:

In [24]: print(r”www.\”flydean\”.com”)
www.\”flydean\”.com

字符串通过 + 来进行连接,也可以使用 * 来进行复制:

In [25]: “www” + “flydean.com”
Out[25]: ‘wwwflydean.com’

In [26]: “www.flydean.com” * 3
Out[26]: ‘www.flydean.comwww.flydean.comwww.flydean.com’

相邻的两个或多个 字符串字面值 (引号引起来的字符)将会自动连接到一起.

In [27]: “www” “flydean.com”
Out[27]: ‘wwwflydean.com’

注意,上面的自动连接操作,只能对两个字面量有效,如果是变量的话则会报错。

字符串会被看做是由字符组成的数组,所以可以通过string[index]的形式来进行访问。

In [28]: site5 = “www.flydean.com”

In [29]: site5[3]
Out[29]: ‘.’

如果索引是负数的话,会从右边开始计数:

In [30]: site5[-3]
Out[30]: ‘c’

因为-0 和 0 是一样的,所以负数是从 -1 开始的。

除了索引,字符串还支持 切片。索引可以得到单个字符,而 切片 可以获取子字符串:

In [31]: site5[1:5]
Out[31]: ‘ww.f’

注意切片的开始总是被包括在结果中,而结束不被包括。这使得 s[:i] + s[i:] 总是等于 s

In [33]: site5[:4]+site5[4:]
Out[33]: ‘www.flydean.com’

切片的索引有默认值,省略开始索引时默认为0。

如果索引超出了字符串的范围就会发送越界错误。

In [34]: site5[100]
—————————————————————————
IndexError Traceback (most recent call last)
<ipython-input-34-fc1f475f725b> in <module>()
—-> 1 site5[100]

IndexError: string index out of range

但是,切片中的越界索引会被自动处理:

In [36]: site5[:100]
Out[36]: ‘www.flydean.com’

因为字符串是不可变的,所以我们不能通过索引的形式来对字符串进行修改:

In [37]: site[2] = “A”
—————————————————————————
TypeError Traceback (most recent call last)
<ipython-input-37-9147d44bd80c> in <module>()
—-> 1 site[2] = “A”

TypeError: ‘str’ object does not support item assignment

len用来统计字符串的长度:

In [38]: len(site5)
Out[38]: 15

字符串对象str
字符串的本质是字符串对象str。

可以看下str的基本方法:

In [39]: site5.
capitalize() encode() format() isalpha() islower() istitle() lower() replace() rpartition() splitlines() title()
casefold() endswith() format_map() isdecimal() isnumeric() isupper() lstrip() rfind() rsplit() startswith() translate()
center() expandtabs() index() isdigit() isprintable() join() maketrans() rindex() rstrip() strip() upper()
count() find() isalnum() isidentifier() isspace() ljust() partition() rjust() split() swapcase() zfill()

感兴趣的同学可以自行去研究。

列表
列表是用方括号表示的数据的集合。列表中的数据可以是多种数据类型,但是一般情况下,我们在一个列表中使用同一个数据类型。

In [40]: ages = [ 10, 14, 18, 20 ,25]

In [41]: ages
Out[41]: [10, 14, 18, 20, 25]

和字符串一样,列表也支持索引和切片。事实上,只要是 sequence 类型的数据类型,都支持索引和切片。

In [42]: ages[3]
Out[42]: 20

In [43]: ages[:2]
Out[43]: [10, 14]

In [44]: ages[:]
Out[44]: [10, 14, 18, 20, 25]

注意,列表的切片会返回一个新的列表。但是这个新的列表是浅拷贝,意味着新列表的元素是原列表中元素的引用。

列表还支持拼接操作:

In [45]: ages + [9, 11]
Out[45]: [10, 14, 18, 20, 25, 9, 11]

和String的不可变性不同,列表是可变的,这就意味着我们可以通过索引来修改列表的值:

In [46]: ages[0] = 100

In [47]: ages
Out[47]: [100, 14, 18, 20, 25]

列表的底层类型是list,我们可以看下list中的方法:

In [51]: ages.
append() count() insert() reverse()
clear() extend() pop() sort()
copy() index() remove()

我们可以使用append来附加list的值,也可以使用count来统计list的元素个数等等。

上面我们提到了,列表的切片是原列表的引用,所以我们可以通过给切片赋值,来修改原始列表的值:

>>> letters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’]
>>> letters
[‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’]
>>> # replace some values
>>> letters[2:5] = [‘C’, ‘D’, ‘E’]
>>> letters
[‘a’, ‘b’, ‘C’, ‘D’, ‘E’, ‘f’, ‘g’]
>>> # now remove them
>>> letters[2:5] = []
>>> letters
[‘a’, ‘b’, ‘f’, ‘g’]
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters

列表还可以进行嵌套,构建多层的列表:

>>> a = [‘a’, ‘b’, ‘c’]
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[[‘a’, ‘b’, ‘c’], [1, 2, 3]]
>>> x[0]
[‘a’, ‘b’, ‘c’]
>>> x[0][1]
‘b’

Python中的流程控制

Python基础之:Python中的流程控制

 

文章目录
简介
while语句
if 语句
for语句
Break
Continue
pass
简介
流程控制无非就是if else之类的控制语句,今天我们来看一下Python中的流程控制会有什么不太一样的地方。

while语句
python中的while语句和其他语言没有什么不一样,我使用while语句来编写一个斐波拉赫数列:

In [56]: while x < 10 :
…: print(x)
…: x, y = y, x+y
…:

if 语句
python中的 if 可以和 elif 或者 else 配合使用:

>>> x = int(input(“Please enter an integer: “))
Please enter an integer: 42
>>> if x < 0:
… x = 0
… print(‘Negative changed to zero’)
… elif x == 0:
… print(‘Zero’)
… elif x == 1:
… print(‘Single’)
… else:
… print(‘More’)

More

if语句很简单,这里就不做过多的介绍。

for语句
Python中的for语句主要用来对序列进行迭代,比如列表或者字符串:

In [57]: ages = [ 10, 14, 18, 20 ,25]

In [58]: for age in ages:
…: print(age)
…:

遍历过程中,为了防止在遍历的时候原序列被修改,我们可以遍历序列的拷贝:

In [59]: for age in ages.copy():
…: print(age)
…:

for语句和range()函数的结合,可以得到不一样的效果。

range()用来生成给定范围内的集合:

In [61]: for age in range(5):
…: print(age)
…:

range()函数还可以带步长作为第三个参数:

In [62]: for age in range(5, 10 , 2):
…: print(age)
…:

Range()和len()组合,可以方便的变量列表:

>>> a = [‘Mary’, ‘had’, ‘a’, ‘little’, ‘lamb’]
>>> for i in range(len(a)):
… print(i, a[i])

0 Mary
1 had
2 a
3 little
4 lamb

Break
break用来跳出*近的for或者while循环。

要注意的是,for循环可以和else一起使用:

In [64]: for n in range(2, 10):
…: for x in range(2, n):
…: if n % x == 0:
…: print(n, ‘equals’, x, ‘*’, n//x)
…: break
…: else:
…: print(n, ‘is a prime number’)
…:
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

循环中的else语句,会在for循环执行完毕,之后执行。如果我们使用break对for循环进行了中断,那么else语句将不会被执行。

Continue
continue用来跳过此次循环中的后面部分,继续执行下一次循环。

还是刚才的例子,我们使用continue进行改装:

In [68]: for n in range(2, 10):
…: for x in range(2, n):
…: if n % x == 0:
…: print(n, ‘equals’, x, ‘*’, n//x)
…: continue
…: else:
…: print(n, ‘is a prime number’)
…:
2 is a prime number
3 is a prime number
4 equals 2 * 2
4 is a prime number
5 is a prime number
6 equals 2 * 3
6 equals 3 * 2
6 is a prime number
7 is a prime number
8 equals 2 * 4
8 equals 4 * 2
8 is a prime number
9 equals 3 * 3
9 is a prime number

可以看到,在continue中,else语句会一直执行。

pass
pass表示的是什么都不做。是一个空的执行。

通常我们使用pass作为函数或条件子语句的占位符,表示具体的内容可以在未来进行填充。

可以在while中使用pass:

>>> while True:
… pass # Busy-wait for keyboard interrupt (Ctrl+C)

可以在类中使用pass:

>>> class MyEmptyClass:
… pass

可以在函数中使用pass:

>>> def initlog(*args):
… pass # Remember to implement this!

Python基础之:函数

Python基础之:函数

文章目录
简介
内置函数
自定义函数
参数的默认值
关键字参数
特殊参数
参数解包
Lambda
函数标注
简介
函数是结构化编程的基础,也是代码复用的基石。Python中通过def来自定义函数。本文将会深入探索Python中函数的秘密。

内置函数
除了用户的自定义函数之外,Python内置了一些非常有用的函数:

内置函数
abs() delattr() hash() memoryview() set()
all() dict() help() min() setattr()
any() dir() hex() next() slice()
ascii() divmod() id() object() sorted()
bin() enumerate() input() oct() staticmethod()
bool() eval() int() open() str()
breakpoint() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()
自定义函数
Python中使用def来定义函数,并使用return来返回特定的值。

看一个简单的函数的例子:

def my_function(x, y, z):
if z > 1:
return z * (x + y)
else:
return z / (x + y)

把我们之前讲的斐波拉赫数列的例子重新用函数来定义,可以这样写:

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

# 调用函数
fib(1000)

函数的内容需要使用空格或者tab来进行缩进。

参数的默认值
在Python中,我们可以给参数设置默认值,这样如果在函数调用的过程中没有传递参数的时候,就会使用默认值作为参数。

在我们之前定义的函数my_function中,我们可以给z设置一个默认值:

def my_function(x, y, z=10):
if z > 1:
return z * (x + y)
else:
return z / (x + y)

这样我们在调用my_function可以只用传递两个参数,*后的z可以使用默认的参数值。

注意,默认值只会执行一次,如果你传入的参数是可变对象(列表,字典和类实例)的话,我们需要注意这个问题:

def f(a, L=[]):
L.append(a)
return L

print(f(1))
print(f(2))
print(f(3))

# 输出
[1]
[1, 2]
[1, 2, 3]

如果不想在后面的调用中共享默认值,那么可以把默认值的赋值放到函数体内部:

def f(a, L=None):
if L is None:
L = []
L.append(a)
return L

关键字参数
我们可以使用key=value的方式对函数进行调用。

还是前面的函数:

def my_function(x, y, z=10):
if z > 1:
return z * (x + y)
else:
return z / (x + y)

我们可以这样调用:

my_function(1,y=3,z=5)
my_function(1,y=3)

但是不能这样用:

my_function(y=3,1)

关键字的参数必须要放在非关键词参数的后面。也不能对参数进行多次赋值:

>>> def function(a):
… pass

>>> function(0, a=0)
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: function() got multiple values for keyword argument ‘a’

通过上面的讨论我们可以看出,Python函数中的参数有两种,一种是带默认值的参数,一种是不带默认值的参数。

注意,不带默认值的参数一定要在带默认值的参数之前 。

看一个错误的例子:

In [69]: def fa(a=100,b,c=200):
…: pass
File “<ipython-input-69-d5678b64f352>”, line 1
def fa(a=100,b,c=200):
^
SyntaxError: non-default argument follows default argument

而向函数传递参数也有两种方式,一种是不带关键字的传递,一种是带关键字的传递。

注意,非关键词参数的传递一定要在关键词参数传递之前。

举个错误的例子:

In [70]: def fa(a,b=100,c=200):
…: pass
…:

In [71]: fa(a=100,30)
File “<ipython-input-71-5a229b8e420e>”, line 1
fa(a=100,30)
^
SyntaxError: positional argument follows keyword argument

那么问题来了,如果有多个关键词参数和多个非关键词参数,有没有简便的方法来定义这样的函数呢?

有的,那就是 *arguments 和 **keywords

*arguments用来接收所有多余的非关键词参数。而**keywords用来接收所有额外的关键词参数。

注意,*arguments一定要出现在 **keywords 的前面。

举个例子:

def cheeseshop(kind, *arguments, **keywords):
print(“– Do you have any”, kind, “?”)
print(“– I’m sorry, we’re all out of”, kind)
for arg in arguments:
print(arg)
print(“-” * 40)
for kw in keywords:
print(kw, “:”, keywords[kw])

我们可以这样调用:

cheeseshop(“Limburger”, “It’s very runny, sir.”,
“It’s really very, VERY runny, sir.”,
shopkeeper=”Michael Palin”,
client=”John Cleese”,
sketch=”Cheese Shop Sketch”)

将会得到下面的结果:

— Do you have any Limburger ?
— I’m sorry, we’re all out of Limburger
It’s very runny, sir.
It’s really very, VERY runny, sir.
—————————————-
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

特殊参数
函数可以按位置传参,可以按照关键词传参,也可以混合传参。

在某些情况下,我们可能需要限制传参的类型,比如只接收按位置传递,只接收按关键词传递,或者只接受混合传递。

看下特殊参数的定义:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
———– ———- ———-
| | |
| 按位置或者关键词 |
| – 只允许按关键词传递
— 只允许按位置传递

注意,参数之间是以 / 和 * 来进行区分的。

我们举个例子:

>>> def standard_arg(arg):
… print(arg)

>>> def pos_only_arg(arg, /):
… print(arg)

>>> def kwd_only_arg(*, arg):
… print(arg)

>>> def combined_example(pos_only, /, standard, *, kwd_only):
… print(pos_only, standard, kwd_only)

上面定义了4种传参方式的函数。

*个函数就是标准形式,可以按位置传递,也可以按关键词传递。

第二个函数只允许按照位置传递。

第三个函数只允许按照关键词来传递。

第四个函数是混合模式。

参数解包
有时候我们需要将列表或者字典的值转换为函数的参数。那么就需要用到参数解包的功能。

* 操作符 可以用来解包列表和元组。

>>> list(range(3, 6)) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args)) # call with arguments unpacked from a list
[3, 4, 5]

** 操作符 可以用来解包字典。

>>> def parrot(voltage, state=’a stiff’, action=’voom’):
… print(“– This parrot wouldn’t”, action, end=’ ‘)
… print(“if you put”, voltage, “volts through it.”, end=’ ‘)
… print(“E’s”, state, “!”)

>>> d = {“voltage”: “four million”, “state”: “bleedin’ demised”, “action”: “VOOM”}
>>> parrot(**d)

Lambda
熟悉java的朋友可能知道,在JDK8中,Java引入了Lambda表达式。同样的Python中也有Lambda。

你可以将Lambda看做是匿名函数。可以在任何需要函数的地方使用Lambda表达式。

看一个Lambda的例子:

>>> def make_incrementor(n):
… return lambda x: x + n

>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)

还可以将lambda的返回值作为参数:

>>> pairs = [(1, ‘one’), (2, ‘two’), (3, ‘three’), (4, ‘four’)]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, ‘four’), (1, ‘one’), (3, ‘three’), (2, ‘two’)]

函数标注
之前我们讨论的是简单的自定义函数形式,我们并不知道函数的参数类型和返回值类型,其实函数可以写得更加详细一些,这就要用到函数标注了。

所谓函数标注就是用户自定义函数中的类型的可选元数据信息。

函数标注是以字典的形式存放在 __annotations__ 属性中的。我们在参数的名称后面加上冒号,后面跟一个表达式,那么这个表达式会被求值为标注的值。对于返回值来说,返回值标注的定义是加上一个组合符号 ->,后面跟一个表达式,该标注位于形参列表和表示 def 语句结束的冒号之间。

举个例子:

>>> def f(ham: str, eggs: str = ‘eggs’) -> str:
… print(“Annotations:”, f.__annotations__)
… print(“Arguments:”, ham, eggs)
… return ham + ‘ and ‘ + eggs

>>> f(‘spam’)
Annotations: {‘ham’: <class ‘str’>, ‘return’: <class ‘str’>, ‘eggs’: <class ‘str’>}
Arguments: spam eggs
‘spam and eggs’

其实使用函数标注写出来的程序更加清晰,可读性更高。

javascript中的Strict模式

javascript中的Strict模式

 

看动画学算法
以动画的方式,图文并茂讲解常用的算法和数据结构,包括各种排序算法、hash、栈、队列、链表、树、散列表、堆、图等,*对物有所值!
flydean程序那些事
¥39.90
订阅博主
文章目录
简介
使用Strict mode
strict mode的新特性
强制抛出异常
简化变量的使用
简化arguments
让javascript变得更加安全
保留关键字和function的位置
总结
简介
我们都知道javascript是一个弱类型语言,在ES5之前,javascript的程序编写具有很强的随意性,我可以称之为懒散模式(sloppy mode)。比如可以使用未定义的变量,可以给对象中的任意属性赋值并不会抛出异常等等。

在ES5中,引入了strict模式,我们可以称之为严格模式。相应的sloppy mode就可以被称为非严格模式。

严格模式并不是非严格模式的一个子集,相反的严格模式在语义上和非严格模式都发生了一定的变化,所以我们在使用过程中,一定要经过严格的测试。以保证在严格模式下程序的执行和非严格模式下的执行效果一致。

使用Strict mode
strict mode会改变javascript的一些表现,我们将会在下一节中进行详细的讲解。

这里先来看一下,怎么使用strict mode。

Strict mode主要用在一个完整的脚本或者function中,并不适用于block {}。 如果在block中使用strict mode是不会生效的。

除此之外,eval中的代码,Function代码,event handler属性和传递给WindowTimers.setTimeout()的string都可以看做是一个完整的脚本。我们可以在其中使用Strict mode。

如果是在script脚本中使用strict模式,可以直接在脚本的*上面加上”use strict”:

// 整个脚本的strict模式
‘use strict’;
var v = “Hi! I’m a strict mode script!”;
同样的我们也可以在function中使用strict模式:

function strict() {
// 函数的strict模式
‘use strict’;
function nested() { return ‘And so am I!’; }
return “Hi! I’m a strict mode function! ” + nested();
}
function notStrict() { return “I’m not strict.”; }

如果使用的是ES6中引入的modules,那么modules中默认就已经是strict模式了,我们不需要再额外的使用”use strict”:

function myModule() {
// 默认就是strict模式
}
export default myModule;
strict mode的新特性
strict mode在语法和运行时的表现上面和非严格模式都发生了一定的变化,接下来,我们一一来看。

强制抛出异常
在js中,有很多情况下本来可能是错误的操作,但是因为语言特性的原因,并没有抛出异常,从而导致*终运行结果并不是所期待的。

如果使用strict模式,则会直接抛出异常。

比如在strict模式中,不允许使用未定义的全局变量:

‘use strict’;

globalVar = 10; //ReferenceError: globalVar is not defined
这样实际上可以避免手误导致变量名字写错而导致的问题。

我再看一些其他的例子:

‘use strict’;

// 赋值给不可写的全局变量,
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// 赋值给不可写的属性
var obj1 = {};
Object.defineProperty(obj1, ‘x’, { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// 赋值给一个get方法
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// 赋值给一个禁止扩展的对象
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = ‘ohai’; // throws a TypeError

Strict模式可以限制删除不可删除的属性,比如构造函数的prototype:

‘use strict’;
delete Object.prototype; // throws a TypeError

禁止对象和函数参数中的重复属性:

‘use strict’;
var o = { p: 1, p: 2 }; // Duplicate declaration

function sum(a, a, c) { // Duplicate declaration
‘use strict’;
return a + a + c;
}
禁止设置基础类型的属性:

(function() {
‘use strict’;

false.true = ”; // TypeError
(14).sailing = ‘home’; // TypeError
‘with’.you = ‘far away’; // TypeError

})();

简化变量的使用
使用Strict模式可以简化变量的使用,让程序代码可读性更强。

首先,strict模式禁止使用with。

with很强大,我们可以通过将对象传递给with,从而影响变量查找的scope chain。也就是说当我们在with block中需要使用到某个属性的时候,除了在现有的scope chain中查找之外,还会在with传递的对象中查找。

with (expression)
statement

使用with通常是为了简化我们的代码,比如:

var a, x, y;
var r = 10;

with (Math) {
a = PI * r * r;
x = r * cos(PI);
y = r * sin(PI / 2);
}

上面的例子中,PI是Math对象中的变量,但是我们可以在with block中直接使用。有点像java中的import的感觉。

下面的例子将会展示with在使用中的问题:

function f(x, o) {
with (o) {
console.log(x);
}
}
们在with block中输出x变量,从代码可以看出f函数传入了一个x变量。但是如果with使用的对象中如果也存在x属性的话,就会出现意想不到的问题。

所以,在strict模式中,with是禁止使用的。

其次是对eval的改动。

传统模式中,eval中定义的变量,将会自动被加入到包含eval的scope中。我们看个例子:

var x = 17;
var evalX = eval(“var x = 42; x;”);
console.log(x);

因为eval中引入了新的变量x,这个x的值将会覆盖*开始定义的x=17. *后我们得到结果是42.

如果加入use strict,eval中的变量将不会被加入到现有的Scope范围中,我们将会得到结果17.

var x = 17;
var evalX = eval(“‘use strict’; var x = 42; x;”);
console.log(x);
这样做的好处是为了避免eval对现有程序逻辑的影响。

在strict模式下面,还不允许delete name:

‘use strict’;

var x;
delete x; // !!! syntax error

eval(‘var y; delete y;’); // !!! syntax error~~

简化arguments
在js中,arguments代表的是参数数组,首先在Strict模式下,arguments是不能作为变量名被赋值的:

‘use strict’;
arguments++;
var obj = { set p(arguments) { } };
try { } catch (arguments) { }
function arguments() { }
var f = new Function(‘arguments’, “‘use strict’; return 17;”);

上面执行都会报错。

另外,在普通模式下,arguments是和命名参数相绑定的,并且arguments[0]和arg同步变化,都表示的是*个参数。

但是如果在strict模式下,arguments表示的是真正传入的参数。

我们举个例子:

function f(a) {
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.log(pair[0]); // 42
console.log(pair[1]); // 42

上面的例子中,arguments[0]是和命名参数a绑定的,不管f传入的是什么值,arguments[0]的值*后都是42.

如果换成strict模式:

function f(a) {
‘use strict’;
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.log(pair[0]); // 42
console.log(pair[1]); // 17

这个模式下arguments[0]接收的是实际传入的参数,我们得到结果17.

在Strict模式下,arguments.callee是被禁用的。通常来说arguments.callee指向的是当前执行的函数,这会阻止虚拟机对内联的优化,所以在Strict模式下是禁止的。

让javascript变得更加安全
在普通模式下,如果我们在一个函数f()中调用this,那么this指向的是全局对象。在strict模式下,这个this的值是undefined。

如果我们是通过call或者apply来调用的话,如果传入的是primitive value(基础类型),在普通模式下this会自动指向其box类(基础类型对应的Object类型,比如Boolean,Number等等)。如果传入的是undefined和null,那么this指向的是global Object。

而在strict模式下,this指向的是传入的值,并不会做转换或变形。

下面的值都是true:

‘use strict’;
function fun() { return this; }
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);

为什么会安全呢?这就意味着,在strict模式下,不能通过this来指向window对象,从而保证程序的安全性。

另外,在普通模式下,我们可以通过fun.caller或者fun.arguments来获取到函数的调用者和参数,这有可能会访问到一些private属性或者不安全的变量,从而造成安全问题。

在strict模式下,fun.caller或者fun.arguments是禁止的。

function restricted() {
‘use strict’;
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker() {
return restricted();
}
privilegedInvoker();

保留关键字和function的位置
为了保证JS标准的后续发展,在strict模式中,不允许使用关键字作为变量名,这些关键字包括implements, interface, let, package, private, protected, public, static 和 yield等。

function package(protected) { // !!!
‘use strict’;
var implements; // !!!

interface: // !!!
while (true) {
break interface; // !!!
}

function private() { } // !!!
}
function fun(static) { ‘use strict’; } // !!!

而对于function来说,在普通模式下,function是可以在任何位置的,在strict模式下,function的定义只能在脚本的顶层或者function内部定义:

‘use strict’;
if (true) {
function f() { } // !!! syntax error
f();
}

for (var i = 0; i < 5; i++) {
function f2() { } // !!! syntax error
f2();
}

function baz() { // kosher
function eit() { } // also kosher
}

总结
Strict模式为JS的后续发展和现有编程模式的规范都起到了非常重要的作用。但是如果我们在浏览器端使用的话,还是需要注意浏览器的兼容性,并做好严格的测试。

Python中的模块

Python基础之:Python中的模块

 

看动画学算法
以动画的方式,图文并茂讲解常用的算法和数据结构,包括各种排序算法、hash、栈、队列、链表、树、散列表、堆、图等,*对物有所值!
flydean程序那些事
¥39.90
订阅博主
文章目录
简介
模块基础
执行模块
模块搜索路径
dir

包的相对路径
简介
Python的解释环境是很好用,但是如果我们需要编写一个大型的程序的时候,解释环境就完全不够用了。这个时候我们需要将python程序保存在一个文件里。通常这个文件是以.py结尾的。

对于大型的应用程序来说,一个文件可能是不够的,这个时候我们需要在文件中引用其他的文件,这样文件就叫做模块。

模块是一个包含Python定义和语句的文件。文件名就是模块名后跟文件后缀 .py 。在模块内部,模块名可以通过全局变量 __name__ 获得。

模块基础
还是之前的斐波拉赫数列的例子,我们在fibo.py文件中存放了函数的实现:

def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=’ ‘)
a, b = b, a+b
print()

编写完毕之后,我们可以在Python的解释环境中导入它:

>>> import fibo
1
然后直接使用即可:

>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

常用的函数,我们可以将其赋值给一个变量:

>>> fib = fibo.fib
>>> fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

或者,我们在导入的时候,直接给这个模块起个名字:

>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

或者导入模块中的函数:

>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

每个模块都有它自己的私有符号表,该表用作模块中定义的所有函数的全局符号表。因此,模块的作者可以在模块内使用全局变量,而不必担心与用户的全局变量发生意外冲突。

执行模块
前面我们提到了可以使用import来导入一个模块,并且 __name__ 中保存的是模块的名字。

和java中的main方法一样,如果我们想要在模块中进行一些测试工作,有没有类似java中main方法的写法呢?

先看一个例子:

if __name__ == “__main__”:
import sys
fib(int(sys.argv[1]))

在模块中,我们需要进行一个判断 __name__ 是不是被赋值为 “__main__”。

我们这样来执行这个模块:

python fibo.py <arguments>

以脚本执行的情况下,模块的 __name__ 属性会被赋值为 __main__ , 这也是例子中为什么要这样写的原因。

看下执行效果:

$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34

如果是以模块导入的话,那么将不会被执行:

>>> import fibo
>>>

模块搜索路径
使用import导入模块的时候,解释器首先会去找该名字的内置模块,如果没找到的话,解释器会从 sys.path变量给出的目录列表里寻找。

sys.path的初始目录包括:

当前目录
PYTHONPATH 指定的目录
安装的默认值
dir
要想查看模块中定义的内容,可以使用dir函数。

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
[‘__builtins__’, ‘__name__’, ‘a’, ‘fib’, ‘fibo’, ‘sys’]

上面的例子列出了当前模块中定义的内容,包括变量,模块,函数等。

注意, dir() 不会列出内置函数和变量的名称。如果你想要这些,它们的定义是在标准模块 builtins 中。

我们可以给dir加上参数,来获取特定模块的内容:

>>> 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’, ‘NameError’, ‘None’, ‘NotADirectoryError’, ‘NotImplemented’,
‘NotImplementedError’, ‘OSError’, ‘OverflowError’,
‘PendingDeprecationWarning’, ‘PermissionError’, ‘ProcessLookupError’,
‘ReferenceError’, ‘ResourceWarning’, ‘RuntimeError’, ‘RuntimeWarning’,
‘StopIteration’, ‘SyntaxError’, ‘SyntaxWarning’, ‘SystemError’,
‘SystemExit’, ‘TabError’, ‘TimeoutError’, ‘True’, ‘TypeError’,
‘UnboundLocalError’, ‘UnicodeDecodeError’, ‘UnicodeEncodeError’,
‘UnicodeError’, ‘UnicodeTranslateError’, ‘UnicodeWarning’, ‘UserWarning’,
‘ValueError’, ‘Warning’, ‘ZeroDivisionError’, ‘_’, ‘__build_class__’,
‘__debug__’, ‘__doc__’, ‘__import__’, ‘__name__’, ‘__package__’, ‘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’]


java中有package的概念,用来隔离程序代码。同样的在Python中也有包。

我们看一个Python中包的例子:

sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py

effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py

filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py

上面我们定义了4个包,分别是sound,sound.formats, sound.effects, sound.filters。

注意,如果是包的话,里面一定要包含 __init__.py 文件。

__init__.py 可以是一个空文件,也可以执行包的初始化代码或设置 __all__ 变量。

当导入的时候, python就会在 sys.path 路径中搜索该包。

包的导入有很多种方式,我们可以导入单个模块:

import sound.effects.echo

但是这样导入之后,使用的时候必须加载全名:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

如果不想加载全名,可以这样导入:

from sound.effects import echo

那么就可以这样使用了:

echo.echofilter(input, output, delay=0.7, atten=4)

还以直接导入模块中的方法:

from sound.effects.echo import echofilter

然后这样使用:

echofilter(input, output, delay=0.7, atten=4)

如果一个包里面的子包比较多,我们可能会希望使用 * 来一次性导入:

from sound.effects import *

那么如何去控制到底会导入effects的哪一个子包呢?

我们可以在 __init__.py 中定义一个名叫 __all__ 的列表,在这个列表中列出将要导出的子包名,如下所示:

__all__ = [“echo”, “surround”, “reverse”]

这样from sound.effects import * 将导入 sound 包的三个命名子模块。

如果没有定义 __all__,from sound.effects import * 语句 不会 从包 sound.effects 中导入所有子模块到当前命名空间;它只会导入包 sound.effects。

包的相对路径
Import 可以指定相对路径,我们使用 . 来表示当前包, 使用 … 来表示父包。

如下所示:

from . import echo
from .. import formats
from ..filters import equalizer

pandas基础篇一

python——pandas基础篇一
pandas的知识很多很细,更多感觉像字典工具一样,自己就打算借助这个平台梳理知识脉络,见证自己的成长!

一、文件的读取和写入
1、文件读取
pandas能读取的文件格式有很多种,主要介绍常用的几种格式(.csv/.txt/.xlsx…)
1
1.1语法
.csv%title插图%num

txt/xlsx

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325142721709.png

1.2 分割参数sep
在读取txt文件时,经常遇到分隔符非空格的情况,read_table有一个分割参数sep,它使得用户可以自定义分割符号,进行txt数据的读取。%title插图%num

2、数据写入
pandas中没有定义to_table函数,但是to_csv可以保存为txt文件,并且允许自定义分隔符,常用制表符\t分割:%title插图%num

读取TXT文件,也可以使用上面的read_table,就可避免分隔符问题了。

pandas基础篇(二)

pandas基础篇(二)
这部分主要整理介绍pandas的基本数据结构及其基础语法
pandas的基本数据结构有两种数据类型:(1)Series
(2) DataFrame

1. Series
1.1 Series的组成
Series的组成由四部分组成:

data :序列的值
index:索引 (索引有它自己的名字属性,默认为NULL)
dtype: 储存类型
name: 序列名字
1.2 定义
#定义Series
import pandas as pd
s = pd.Series(data = [100, ‘a’, {‘dic1’:5}],
index = pd.Index([‘id1’, 20, ‘third’], name=’my_idx’),
dtype = ‘object’,
name = ‘my_name’)
s

运行截图%title插图%num

Object:代表了一种混合类型。正如上面所示,data里既有字符串,又有整数,字典形式等。此外,pandas把纯字符串序列也默认认为是一种object类型的序列,但它也可以用string类型存储。

1.3 Series获取属性
series获取属性,其实和java类似,都是以”.”的方式获取属性和方法。

#获取属性代码如下:
s.values #获取data值,得写成values,不能直接写data
s.index
s.dtype
s.name

部分代码运行截图:%title插图%num

2. DataFrame
DataFrame在Series的基础上增加了列索引,一个数据框可以由二维的data与行列索引来构造:

2.1 两种定义方式
普通定义
data = [[1, ‘a’, 1.2], [2, ‘b’, 2.2], [3, ‘c’, 3.2]]
df = pd.DataFrame(data = data,
index = [‘row_%d’%i for i in range(3)],
columns=[‘col_0’, ‘col_1’, ‘col_2’])
df

运行截图%title插图%num

常用方式
采用从列索引名到数据的映射来构造数据框,同时再加上行索引:
df = pd.DataFrame(data = {‘col_0’: [1,2,3],
‘col_1’:list(‘abc’),
‘col_2’: [1.2, 2.2, 3.2]},
index = [‘row_%d’%i for i in range(3)])
df

2.2 获取属性
与Series类似,在数据框中同样可以取出相应的属性

df.values
df.index

2.3 .T转置
通过.T可以把DataFrame进行转置:

df.T%title插图%num

python基础篇(三)

python基础篇(三)
这篇主要整理pandas常用的基本函数,主要分为五部分:

汇总函数
特征统计函数
唯一值函数
替换函数
排序函数
1、汇总函数
常用的主要是4个:

tail(): 返回表或序列的后n行
head(): 返回表或序列的前n行
info(): 返回表的信息概况
describe(): 返回表中数值列对应的主要统计量
n默认为5
df.describe()

#运行截图
Height Weight
count 183.000000 189.000000
mean 163.218033 55.015873
std 8.608879 12.824294
min 145.400000 34.000000
25% 157.150000 46.000000
50% 161.900000 51.000000
75% 167.500000 65.000000
max 193.900000 89.000000

2、特征统计函数
在Series和DataFrame上定义了许多统计函数,*常见的是:

sum
mean (均值)
median (中位数)
var (方差)
std (标准差)
max
min
用法示例
df_demo = df[[‘Height’, ‘Weight’]]
df_demo.mean()
1
2
聚合函数
quantile (返回分位数)
count (返回非缺失值个数)
idxmax (*大值对应的索引)
聚合函数,有一个公共参数axis,axis=0代表逐列聚合,axis=1表示逐行聚合

df_demo.mean(axis=1).head()
1
3、唯一值函数
唯一值函数常用的四个函数:

unique() : 得到唯一值组成的列表->统计出指定列唯一存在的值有哪些
nunique() :唯一值的个数->统计出指定列唯一存在的值总共有多少个
value_counts() : 得到唯一值和其对应出现的频数
drop_duplicates() : 去重
duplicated()
drop_duplicates()基本用法
关键参数keep
first : 保留*次出现的重复行,删除后面的重复行
last : 删除重复项,除了*后一次出现
False:把所有重复组合所在的行剔除。
需要指定列
代码:

#原本的数据样例
df_demo = df[[‘Gender’,’Transfer’,’Name’]]
df_demo

Gender Transfer Name
0 Female N Gaopeng Yang
1 Male N Changqiang You
2 Male N Mei Sun
3 Female N Xiaojuan Sun
4 Male N Gaojuan You
… … … …
195 Female N Xiaojuan Sun
196 Female N Li Zhao
197 Female N Chengqiang Chu
198 Male N Chengmei Shen
199 Male N Chunpeng Lv
200 rows × 3 columns

#现给Gender,Transfer两列去重
df_demo.drop_duplicates([‘Gender’,’Transfer’])

Gender Transfer Name
0 Female N Gaopeng Yang
1 Male N Changqiang You
12 Female NaN Peng You
21 Male NaN Xiaopeng Shen
36 Male Y Xiaojuan Qin
43 Female Y Gaoli Feng

由此可见,使用了first参数,保留*次出现的重复行,删除后面的重复行
在未指定参数的情况下,keep默认first;

指定last
案例如下:

df_demo.drop_duplicates([‘Gender’, ‘Transfer’], keep=’last’)
1
Gender Transfer Name
147 Male NaN Juan You
150 Male Y Chengpeng You
169 Female Y Chengquan Qin
194 Female NaN Yanmei Qian
197 Female N Chengqiang Chu
199 Male N Chunpeng Lv

last:删除所有的重复行,只保留出现的*后一个
drop_duplicates() & duplicated()的区别
duplicated和drop_duplicates的功能类似,但前者返回了是否为唯一值的布尔列表,其keep参数与后者一致。其返回的序列,把重复元素设为True,否则为False。 drop_duplicates等价于把duplicated为True的对应行剔除。
4、替换函数
替换函数有三类:

映射函数:replace()…
逻辑函数:(1)where (2)mask
数值替换
replace的用法
#原本的数据
df_demo = df[[‘Gender’,’Transfer’,’Name’]]
df_demo

Gender Transfer Name
0 Female N Gaopeng Yang
1 Male N Changqiang You
2 Male N Mei Sun
3 Female N Xiaojuan Sun
4 Male N Gaojuan You
… … … …
195 Female N Xiaojuan Sun
196 Female N Li Zhao
197 Female N Chengqiang Chu
198 Male N Chengmei Shen
199 Male N Chunpeng Lv
200 rows × 3 columns
1
#替换Gender,女替换为0,男替换为1
df[‘Gender’].replace({‘Female’:0, ‘Male’:1}).head()

Name: Gender, dtype: int64

逻辑替换
逻辑替换包括了where和mask,这两个函数是完全对称的:where函数在传入条件为False的对应行进行替换,而mask在传入条件为True的对应行进行替换,当不指定替换值时,替换为缺失值(NAN)

s = pd.Series([-1, 1.2345, 100, -50])
s.where(s<0)

0 -1.0
1 NaN
2 NaN
3 -50.0
dtype: float64

s.where(s<0, 100)

0 -1.0
1 100.0
2 100.0
3 -50.0
dtype: float64

s.mask(s<0)

0 NaN
1 1.2345
2 100.0000
3 NaN
dtype: float64

python爬虫–协程

python爬虫–协程
基本知识
event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足某些条件的时候,函数就会被循环执行。
coroutine:携程对象,我们可以将携程对象注册到事件循环中,它会被时间循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用时不会被立即执行,而是返回一个协程对象。
task:任务,它是对协程对象的进一步封装, 包含了任务的各个状态。
future:代表将来执行或还没有执行的任务,实际上和task 没有本质区别。
async定义-个协程.
await用来挂起阻塞方法的执行。
协程的基本使用
import asyncio

async def request(url):
print(‘正在请求的url是:’,url)
print(‘请求成功:’,url)
#async修饰的函数,调用之后返回的一个协程对象
c = request(‘www.baidu.com’)

# #创建一个事件循环对象
# loop = asyncio.get_event_loop()
#
# #将携程对象注册到loop中,然后启动loop
# loop.run_until_complete(c)

# #task的使用
# loop = asyncio.get_event_loop()
# #基于loop创建一个task对象
# task = loop.create_task(c)
# print(task)
# loop.run_until_complete(task)
# print(task)

#future的使用
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(c)
print(task)
loop.run_until_complete(task)
print(task)

多任务协程实现
import asyncio
import time

async def request(url):
print(‘正在请求的url是:’,url)
#在异步协程中如果出现同步模块相关的代码,那么就无法实现异步
#time.sleep(2)
await asyncio.sleep(2)
print(‘请求成功:’,url)
#async修饰的函数,调用之后返回的一个协程对象
start = time.time()
urls = {
‘www.123.com’,
‘www.234.com’,
‘www.345.com’
}
#存放多个任务对象
stask = []
for url in urls:
c = request(url)
task = asyncio.ensure_future(c)
stask.append(task)
loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(stask))

print(time.time()-start)

多任务协程异步实现
在进行多任务协程实现前,还需要建立一个简单的本地http服务

from flask import Flask
import time

app = Flask(__name__)

@app.route(‘/azb’)
def index_azb():
time.sleep(2)
return ‘Hello azb’

@app.route(‘/xx’)
def index_xx():
time.sleep(2)
return ‘Hello xx’

@app.route(‘/hh’)
def index_hh():
time.sleep(2)
return ‘Hello hh’

if __name__ == ‘__main__’:
app.run(threaded=True)

%title插图%num
实现

import requests,asyncio,time

start = time.time()
urls = [
‘http://127.0.0.1:5000/azb’,’http://127.0.0.1:5000/xx’,’http://127.0.0.1:5000/hh’
]

async def get_page(url):
print(‘正在下载’,url)
#request是基于同步,必须使用基于异步的网络请求模块
response = requests.get(url=url)
print(‘下载成功!’,url)

tasks = []

for url in urls:
c = get_page(url)
task = asyncio.ensure_future(c)
tasks.append(task)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(‘总耗时’,time.time()-start)
%title插图%num

aiohttp模块引入
import requests,asyncio,time,aiohttp

start = time.time()
urls = [
‘http://127.0.0.1:5000/azb’,’http://127.0.0.1:5000/xx’,’http://127.0.0.1:5000/hh’
]

async def get_page(url):
async with aiohttp.ClientSession() as session:
async with await session.get(url) as response:
#text()返回字符串形式的响应数据
#read()返回的二进制形式的响应数据
#json()返回的就是json对象
#获取响应数据操作之前一定要使用await进行手动挂起

page_text = await response.text()
print(page_text)

tasks = []

for url in urls:
c = get_page(url)
task = asyncio.ensure_future(c)
tasks.append(task)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(‘总耗时’,time.time()-start)%title插图%num

 

协程还是没有理解

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速