查找迭代中最常见的元素
# collections.Counter 允许您在一个迭代中查找最常见的元素:
>>> import collections
>>> c = collections.Counter('helloworld')
>>> c
Counter({'l': 3, 'o': 2, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1})
>>> c.most_common(3)
[('l', 3), ('o', 2), ('e', 1)]
# collections.Counter 允许您在一个迭代中查找最常见的元素:
>>> import collections
>>> c = collections.Counter('helloworld')
>>> c
Counter({'l': 3, 'o': 2, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1})
>>> c.most_common(3)
[('l', 3), ('o', 2), ('e', 1)]
# 什么时候用__repr__ 和 __str__模拟std库的功能:
>>> import datetime
>>> today = datetime.date.today()
# __str__ 摔交的结果应是可读的:
>>> str(today)
'2017-02-02'
# __repr__的结果应明确如下:
>>> repr(today)
'datetime.date(2017, 2, 2)'
# Python解释器会话使用__repr__检查对象:
>>> today
datetime.date(2017, 2, 2)
# 您可以使用Python内置的“dis”模块来反汇编函数并检查它们的CPython VM字节码
>>> def greet(name):
... return 'Hello, ' + name + '!'
>>> greet('Dan')
'Hello, Dan!'
>>> import dis
>>> dis.dis(greet)
2 0 LOAD_CONST 1 ('Hello, ')
2 LOAD_FAST 0 (name)
4 BINARY_ADD
6 LOAD_CONST 2 ('!')
8 BINARY_ADD
10 RETURN_VALUE
# 您可以以字符串的形式获得对象类的名称
>>> class MyClass: pass
>>> obj = MyClass()
>>> obj.__class__.__name__
'MyClass'
# 函数也有类似的特性:
>>> def myfunc(): pass
>>> myfunc.__name__
'myfunc'
# 您可以使用内置的“issubclass()”检查类继承关系
>>> class BaseClass: pass
>>> class SubClass(BaseClass): pass
>>> issubclass(SubClass, BaseClass)
True
>>> issubclass(SubClass, object)
True
>>> issubclass(BaseClass, SubClass)
False
# Python 3允许使用unicode变量名:
>>> π = math.pi
>>> class Spin̈alTap: pass
>>> Spin̈alTap()
<Spin̈alTap object at 0x10e58d908>
# 然而,只有类似字母的字符可以工作
>>> 🍺 = "beer"
SyntaxError:
"invalid character in identifier"
# "globals()"返回当前范围内所有全局变量的dict:
>>> globals()
{...}
# “locals()”执行相同的操作,但对当前范围内的所有局部变量都适用
>>> locals()
{...}
# Python 3.3+有一个std lib模块,即使在Python“dies”(例如节段错误)时也可以显示回溯
import faulthandler
faulthandler.enable()
# 也可以通过命令行中的“python -X faulthandler”来启用。
天授 是一个基于 PyTorch 的深度强化学习平台。
CartPole-v0 是一个很简单的离散动作空间场景,DQN 也是为了解决这种任务。在使用不同种类的强化学习算法前,您需要了解每个算法是否能够应用在离散动作空间场景 / 连续动作空间场景中,比如像 DDPG [LHP+16] 就只能用在连续动作空间任务中,其他基于策略梯度的算法可以用在任意这两个场景中。
# 虚拟环境("virtualenvs")将项目依赖关系分离开来。
# 它们可以帮助您避免包和Python运行时的不同版本之间的版本冲突。
# 在创建和激活virtualenv之前:“python”和“pip”映射
# 到python解释器的系统版本( Python 2.7)
$ which python
/usr/local/bin/python
# 让我们使用另一个版本的Python创建一个新的virtualenv(Python 3)
$ python3 -m venv ./venv
# virtualenv只是一个“文件夹中的Python环境”
$ ls ./venv
bin include lib pyvenv.cfg
# 激活virtualenv可以配置当前shell会话,
# 以使用来自virtualenv文件夹的python(和pip)命令,而不是全局环境
$ source ./venv/bin/activate
# 请注意,激活一个virtualenv是如何修改shell提示符的,
# 提示中显示了virtualenv文件夹的名称
(venv) $ echo "wee!"
# 使用active virtualenv,“python”命令映射到active virtualenv
# 内部的解释器二进制
(venv) $ which python
/Users/dan/my-project/venv/bin/python3
# 使用“pip”安装新的库和框架,现在就会将它们安装到virtualenv沙箱
# 中,这样全局环境(以及其他virtualenvs)就不会被修改
(venv) $ pip install requests
# 要回到全局Python环境,请运行以下命令
(venv) $ deactivate
# 看看提示符是如何再次变为“正常”的
$ echo "yay!"
# 停用virtualenv将“python”和“pip”命令翻转回全局环境
$ which python
/usr/local/bin/python
# Python的' for '和' while '循环支持' else '子句,
# 该子句仅在循环结束而没有碰到' break '语句时执行。
def contains(haystack, needle):
"""
Throw a ValueError if `needle` not
in `haystack`.
"""
for item in haystack:
if item == needle:
break
else:
# 这里的“else”是一个“completion子句”,
# 它只在循环运行到补全而没有碰到“break”语句时运行。
raise ValueError('Needle not found')
>>> contains([23, 'needle', 0xbadc0ffee], 'needle')
None
>>> contains([23, 42, 0xbadc0ffee], 'needle')
ValueError: "Needle not found"
# 就个人而言,我不喜欢循环中的“else”“completion子句”,
# 因为我觉得它很混乱。我宁愿做这样的事
def better_contains(haystack, needle):
for item in haystack:
if item == needle:
return
raise ValueError('Needle not found')
# 注意:通常您会编写类似这样的内容来进行成员资格测试,
# 这更符合python的风格
if needle not in haystack:
raise ValueError('Needle not found')
# Python的' for '和' while '循环支持' else '子句,该子句仅在循环结束而没有碰到' break '语句时执行。
def contains(haystack, needle):
"""
Throw a ValueError if `needle` not
in `haystack`.
"""
for item in haystack:
if item == needle:
break
else:
# 这里的“else”是一个“completion子句”,
# 它只在循环运行到完成时没有碰到“break”语句时运行
raise ValueError('Needle not found')
>>> contains([23, 'needle', 0xbadc0ffee], 'needle')
None
>>> contains([23, 42, 0xbadc0ffee], 'needle')
ValueError: "Needle not found"
# 就个人而言,我不喜欢循环中的“else”“completion子句”,
# 因为我觉得它很混乱。我宁愿做这样的事
def better_contains(haystack, needle):
for item in haystack:
if item == needle:
return
raise ValueError('Needle not found')
# 注意:通常您会编写类似这样的内容来进行成员资格测试,
# 这更符合python的风格
if needle not in haystack:
raise ValueError('Needle not found')
# 检查列表中所有项是否相等的python方法
>>> lst = ['a', 'a', 'a']
>>> len(set(lst)) == 1
True
>>> all(x == lst[0] for x in lst)
True
>>> lst.count(lst[0]) == len(lst)
True
# 我从“最python化”到“最python化”,从“最低效”到“最高效”。
# len(set())解决方案是惯用的,但是构造一个集合在内存和速度方面效率较低。
# 在Python 3.4+中,可以使用context .suppress()选择性地忽略特定异常
import contextlib
with contextlib.suppress(FileNotFoundError):
os.remove('somefile.tmp')
# 这相当于:
try:
os.remove('somefile.tmp')
except FileNotFoundError:
pass
# contextlib.suppress docstring:
#
# "返回一个上下文管理器,如果在with语句的主体中出现任何指定的异常,该上下文管理器
# 将抑制这些异常,然后在with语句结束后继续执行第一个语句。
# 在Python3中,你可以使用一个“*”的星号。在函数参数列表中强制执行调用者使用关键字参数的某些参数:
>>> def f(a, b, *, c='x', d='y', e='z'):
... return 'Hello'
# 为了传递c、d和e的值,您需要显式地将其作为“key=value”命名的参数传递
>>> f(1, 2, 'p', 'q', 'v')
TypeError:
"f() takes 2 positional arguments but 5 were given"
>>> f(1, 2, c='p', d='q',e='v')
'Hello'
# Python 3.5+允许传递多个集合关键字参数(“kwargs”)到一个#函数在单个调用中使用“**”语法
>>> def process_data(a, b, c, d):
>>> print(a, b, c, d)
>>> x = {'a': 1, 'b': 2}
>>> y = {'c': 3, 'd': 4}
>>> process_data(**x, **y)
1 2 3 4
>>> process_data(**x, c=23, d=42)
1 2 23 42
Object.create(Array).length === 1 //true
Object.keys(Object.create(Array)).length === 0 //true
为什么呢?
wtfjs 收集了一些反常识的 js 代码片段,但这些代码的执行流程都是有文档可参考的,本系列主要是通过解释这些代码来帮助读者复习与进一步了解 JavaScript。
!! 与 == 的转换规则一样吗?详细的转换规则是什么?
去抖和节流是什么?是怎么减少频繁操作的?如何实现这两个函数?