所有讨论都是关于python 3.1.2; 请参阅Python文档以获取我的问题的来源.
我知道什么zip呢; 我只是不明白为什么它可以像这样实现:
def zip(*iterables):
# zip('ABCD', 'xy') --> Ax By
iterables = map(iter, iterables)
while iterables:
yield tuple(map(next, iterables))
Run Code Online (Sandbox Code Playgroud)
比方说我打电话zip(c1, c2, c3).如果我理解正确,iterables最初是元组(c1,c2,c3).
该行将其iterables = map(iter, iterables)转换为迭代器,如果迭代,它将返回iter(c1),iter(c2),iter(c3).
在循环中,map(next, iterables)是会返回一个迭代器next(iter(c1)),next(iter(c2))以及next(iter(c3))如果通过迭代.的tuple通话将其转换为(next(iter(c1)), next(iter(c2)), next(iter(c3)),用尽其参数(iterables据我可以告诉在第一个调用).我不明白while循环如何继续,因为它检查iterables; 如果它继续,为什么tuple调用不返回空元组(迭代器耗尽).
我确定我错过了很简单的东西..
我正在使用Dive Into Python 3学习Python .我喜欢它,但我不理解6.5节中用于介绍Closures的示例.
我的意思是,我知道它是如何工作的,我觉得这很酷.但我没有看到任何真正的好处:在我看来,通过简单地在循环中逐行读取规则文件,并对每行读取进行搜索/替换,可以实现相同的结果.
有人可以帮助我:
或者理解为什么在这个例子中使用闭包改进了代码(例如,更容易维护,扩展,重用或调试?)
或建议一些其他真实代码示例的来源,其中闭包真正发光?
谢谢!
Python 3.2文档是指Collin Winter的functional模块,其中包含以下功能compose:
compose()函数实现了函数组合.换句话说,它返回外部和内部callables周围的包装器,这样内部的返回值直接送到外部.
不幸的是,这个模块自2006年7月以来一直没有更新; 我想知道是否有任何更换.
现在,我只需要compose功能.以下原始functional.compose定义是否仍适用于Python 3?
def compose(func_1, func_2, unpack=False):
"""
compose(func_1, func_2, unpack=False) -> function
The function returned by compose is a composition of func_1 and func_2.
That is, compose(func_1, func_2)(5) == func_1(func_2(5))
"""
if not callable(func_1):
raise TypeError("First argument to compose must be callable")
if not callable(func_2):
raise TypeError("Second argument to compose must be callable")
if unpack:
def composition(*args, **kwargs):
return func_1(*func_2(*args, **kwargs))
else:
def …Run Code Online (Sandbox Code Playgroud) python functional-programming function function-composition python-3.x
假设我想创建一个函数,它将lambda函数(Callable)作为参数,其中lambda函数将向量作为输入(定义为numpy数组或numpy矩阵)并返回一个新向量.如何使用numpy类型声明Callable的类型签名?
我最初的尝试看起来像这样:
def some_func(calc_new_vector: Callable[[np.array], np.array], ...other-params...) -> SomeType:
...do stuff...
...return...
Run Code Online (Sandbox Code Playgroud)
但是,这会在运行解释器时导致错误:
TypeError: Callable[[arg, ...], result]: each arg must be a type. Got <built-in function array>.
Run Code Online (Sandbox Code Playgroud) 通过重复的字符串连接来构建字符串是一种反模式,但我仍然很好奇为什么它的性能在字符串长度超过大约10**6后从线性切换到二次方:
# this will take time linear in n with the optimization
# and quadratic time without the optimization
import time
start = time.perf_counter()
s = ''
for i in range(n):
s += 'a'
total_time = time.perf_counter() - start
time_per_iteration = total_time / n
Run Code Online (Sandbox Code Playgroud)
例如,在我的机器上(Windows 10,python 3.6.1):
10 ** 4 < n < 10 ** 6,time_per_iteration几乎完全恒定在170±10μs10 ** 6 < n,time_per_iteration几乎是完全线性的,达到520μs n == 10 ** 7.线性增长time_per_iteration相当于二次增长total_time. …
我在Python 3中复制了一小块Sugarscape代理仿真模型.我发现我的代码的性能比NetLogo慢约3倍.它可能是我的代码的问题,还是它可能是Python的固有限制?
显然,这只是代码的一个片段,但是Python花费了三分之二的运行时间.我希望如果我写了一些非常低效的东西,它可能会出现在这个片段中:
UP = (0, -1)
RIGHT = (1, 0)
DOWN = (0, 1)
LEFT = (-1, 0)
all_directions = [UP, DOWN, RIGHT, LEFT]
# point is just a tuple (x, y)
def look_around(self):
max_sugar_point = self.point
max_sugar = self.world.sugar_map[self.point].level
min_range = 0
random.shuffle(self.all_directions)
for r in range(1, self.vision+1):
for d in self.all_directions:
p = ((self.point[0] + r * d[0]) % self.world.surface.length,
(self.point[1] + r * d[1]) % self.world.surface.height)
if self.world.occupied(p): # checks if p is in a lookup …Run Code Online (Sandbox Code Playgroud) 有几次我意外地将输入修改为一个函数.由于Python没有常量引用,我想知道什么编码技术可以帮助我避免经常犯这个错误?
例:
class Table:
def __init__(self, fields, raw_data):
# fields is a dictionary with field names as keys, and their types as value
# sometimes, we want to delete some of the elements
for field_name, data_type in fields.items():
if some_condition(field_name, raw_data):
del fields[field_name]
# ...
# in another module
# fields is already initialized here to some dictionary
table1 = Table(fields, raw_data1) # fields is corrupted by Table's __init__
table2 = Table(fields, raw_data2)
Run Code Online (Sandbox Code Playgroud)
当然修复是在更改之前复制参数:
def __init__(self, fields, raw_data):
fields = …Run Code Online (Sandbox Code Playgroud) 在许多情况下,有两种实现选择:闭包和可调用类.例如,
class F:
def __init__(self, op):
self.op = op
def __call__(self, arg1, arg2):
if (self.op == 'mult'):
return arg1 * arg2
if (self.op == 'add'):
return arg1 + arg2
raise InvalidOp(op)
f = F('add')
Run Code Online (Sandbox Code Playgroud)
要么
def F(op):
if op == 'or':
def f_(arg1, arg2):
return arg1 | arg2
return f_
if op == 'and':
def g_(arg1, arg2):
return arg1 & arg2
return g_
raise InvalidOp(op)
f = F('add')
Run Code Online (Sandbox Code Playgroud)
在任何一个方向上做出选择时应该考虑哪些因素?
我能想到两个:
似乎关闭总会有更好的表现(不能想到一个反例).
我认为有些情况下关闭不能完成工作(例如,如果其状态随时间变化).
我在这些方面是否正确?还能添加什么?
当我检查它在列表或集合中的存在时,NaN处理得很好.但我不明白怎么做.[更新:不,不是; 如果找到相同的NaN实例,则报告存在; 如果只发现不同的NaN实例,则报告为缺席.
我认为列表中的存在是通过相等来测试的,所以我预计NaN不会被发现,因为NaN!= NaN.
hash(NaN)和hash(0)都是0.字典和集合如何告诉NaN和0分开?
使用in运算符检查任意容器中NaN的存在是否安全?还是依赖于实现?
我的问题是关于Python 3.2.1; 但如果在未来的版本中存在/计划的任何更改,我也想知道.
NaN = float('nan')
print(NaN != NaN) # True
print(NaN == NaN) # False
list_ = (1, 2, NaN)
print(NaN in list_) # True; works fine but how?
set_ = {1, 2, NaN}
print(NaN in set_) # True; hash(NaN) is some fixed integer, so no surprise here
print(hash(0)) # 0
print(hash(NaN)) # 0
set_ = {1, 2, 0}
print(NaN in set_) # False; works fine, but how?
Run Code Online (Sandbox Code Playgroud)
请注意,如果我将一个用户定义的类的实例添加到a list …
从迭代中删除项目通常会导致RuntimeError: dictionary changed size during iteration异常:
d = {1: 2}
# exception raised
for k in d:
del d[k]
Run Code Online (Sandbox Code Playgroud)
更确切地说,删除本身将成功.但是,要进入下一轮迭代,解释器必须调用next(it),it通过之前获得的字典,迭代器在哪里.此时,next()会注意到字典大小发生了变化,并抱怨.
到现在为止还挺好.但是如果我们都删除并添加项目到字典呢?
d = {1: 1}
# no exception raised
for k in d:
# order of next two lines doesn't matter
d[k*10] = k*10
del d[k]
Run Code Online (Sandbox Code Playgroud)
我几乎可以肯定这不安全(文档暗示在迭代期间不允许插入或删除).为什么解释器允许此代码无错运行?
我唯一的猜测是,每当调用insert或delete方法时,检查哪些迭代器无效是太昂贵了.所以dict不要尝试完善提出这个例外.相反,它只是跟踪每个迭代器内部字典的大小,并在实际要求迭代器移动到下一个项目时检查它是否未更改.有没有办法能够以低成本实现全面验证?
python ×10
python-3.x ×6
closures ×2
performance ×2
coding-style ×1
containers ×1
cpython ×1
dictionary ×1
equality ×1
function ×1
iterator ×1
nan ×1
netlogo ×1
numpy ×1
python-3.5 ×1
simulation ×1
typing ×1
zip ×1