给定自我索引(不确定这是否是正确的术语)numpy数组,例如:
a = np.array([3, 2, 0, 1])
Run Code Online (Sandbox Code Playgroud)
这表示这种排列(=>是一个箭头):
0 => 3
1 => 2
2 => 0
3 => 1
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个表示逆变换的数组,而不是在python中"手动"执行它,也就是说,我想要一个纯粹的 numpy解决方案.我想在上面的例子中得到的结果是:
array([2, 3, 1, 0])
Run Code Online (Sandbox Code Playgroud)
这相当于
0 <= 3 0 => 2
1 <= 2 or 1 => 3
2 <= 0 2 => 1
3 <= 1 3 => 0
Run Code Online (Sandbox Code Playgroud)
看起来很简单,但我想不出怎么做.我试过谷歌搜索,但没有找到任何相关的.
子进程模块具有便捷功能call,在2.6和3.1中都是这样实现的:
def call(*popenargs, **kwargs):
return Popen(*popenargs, **kwargs).wait()
Run Code Online (Sandbox Code Playgroud)
该功能的文档带有红色警告,阅读:
警告:比如
Popen.wait(),当使用stdout=PIPE和/或stderr=PIPE子进程生成足够的输出到管道时它会死锁,这样它就会阻塞等待OS管道缓冲区接受更多数据.
该Popen.wait()文件说,使用Popen.communicate(),而不是在这种情况下.那么,为什么不call只是像下面那样实现,所以可以删除愚蠢的警告,并从标准库中删除这样的愚蠢限制?
def call(*args, **kwargs):
input = kwargs.pop("input", None)
p = Popen(*args, **kwargs)
p.communicate(input)
return p.returncode
Run Code Online (Sandbox Code Playgroud)
我确定这是有原因的.我错过了什么?
我在列表中有0个或更多的dicts:
>>> dicts = [dict(a=3, b=89, d=2), dict(a=3, b=89, c=99), dict(a=3, b=42, c=33)]
Run Code Online (Sandbox Code Playgroud)
我想创建一个新的dict,它只包含上述所有字符串中的键,并且只有值完全相同时:
>>> dict_intersection(*dicts)
{"a": 3}
Run Code Online (Sandbox Code Playgroud)
我觉得应该有一种优雅的写作方式dict_intersection,但我自己只会提出不优雅和/或低效的解决方案.建议?
我正在查看内置argparse._AppendAction的源代码,它实现了"append"操作,并对它的实现方式感到困惑:
def __call__(self, parser, namespace, values, option_string=None):
items = _copy.copy(_ensure_value(namespace, self.dest, []))
items.append(values)
setattr(namespace, self.dest, items)
Run Code Online (Sandbox Code Playgroud)
要打破它:
_ensure_value就像dict.setdefault属性一样.也就是说,如果namespace有一个带有名称的属性,self.dest则返回它,如果没有,则将其设置为[]并返回._copy.copy(x)返回一个浅表副本.什么x是列表,它就像list(x)(但更慢).namespace.self.dest属性namespace被副本覆盖,这应该导致旧列表被垃圾收集.为什么会以这样一种迂回而低效的方式,为每个附加物扔掉一个完整的清单?为什么这不够?
def __call__(self, parser, namespace, values, option_string=None):
items = _ensure_value(namespace, self.dest, [])
items.append(values)
Run Code Online (Sandbox Code Playgroud) from contextlib import contextmanager
@contextmanager
def context():
print "entering"
yield
print "exiting"
def test():
with context():
for x in range(10):
yield x
for x in test():
if x == 5:
break # or raise
Run Code Online (Sandbox Code Playgroud)
输出:
entering
Run Code Online (Sandbox Code Playgroud)
__exit__当for-loop被中断时,有没有办法让python自动调用context()的方法?或者其他一些实现相同目标的方式?我对生成器和上下文管理器的了解让我怀疑它是不可能的,但是这使得上下文管理器在内部生成器中相当无用,不是吗?在我看来,块yield内的语句with应该引发一个红旗,上下文管理器__exit__可能无法运行.
我一直在想应该有这样的功能,但我已经找遍了可能的地方(谷歌,itertools文档,列表法,其他做题),但无处发现相当有什么我一直在寻找.
天真和工作实施:
def split_at_first_false(pred, seq):
first = []
second = []
true_so_far = True
for item in seq:
if true_so_far and pred(item):
first.append(item)
else:
true_so_far = False
second.append(item)
return first, second
print split_at_first_false(str.isalpha, "abc1a2b")
# (['a', 'b', 'c'], ['1', 'a', '2', 'b'])
Run Code Online (Sandbox Code Playgroud)
它有效,但感觉不对.应该有更好的方法来做到这一点!
编辑:我在审核答案后最终使用了一个稍微修改过的senderle的最终建议版本:
from itertools import chain
def split_at_pred(pred, seq):
head = []
it = iter(seq)
for i in it:
if not pred(i):
head.append(i)
else:
return iter(head), chain([i], it)
return iter(head), iter([])
Run Code Online (Sandbox Code Playgroud)
它简洁而优雅,输出是两个迭代器,无论输入(字符串,列表,迭代器),作为奖励,它甚至可以使用以下输入:
from itertools import …Run Code Online (Sandbox Code Playgroud) 我想知道是否存在允许我做这样的事情的python模块:
x = MagicNumber()
x.value = 3
y = 2 * (x + 2) ** 2 - 8
print y # 42
x.value = 2
print y # 24
Run Code Online (Sandbox Code Playgroud)
因此,MagicNumber将实现所有特殊的运算符方法,并且它们都将返回MagicNumber的实例,同时跟踪执行的操作.有这样的课吗?
编辑:澄清
我想在一个模块中使用它,该模块应该记住用户希望执行的某些任意计算的许多参数.因此,用户将设置参数,然后使用它们来生成结果.然后如果他决定改变参数,那么改变会立即反映在他的结果中.因此,只有一个参数实例的非常简化的使用会话将如下所示:
p = MyParams()
p.distance = 13.4 # I use __getattr__ and __setattr__ such that
p.speed = 3.14 # __getattr__ returns MagicNumber instances
time = p.distance / p.speed
Run Code Online (Sandbox Code Playgroud)
编辑2:更多澄清
好的,我会从一开始就做我应该做的.我会提供上下文.
您是一名工程师,您将制作一份LaTeX文档,详细说明某些原型小工具的工作原理和属性.对于不同的原型,这是一项重复的任务.你写了一个小的LaTeX python接口.对于每个原型,您创建一个生成必需文档的python模块.在其中输入LaTeX代码,同时根据需要计算变量,以便计算在上下文中.过了一会你就发现了两个问题:
出于这个问题出现了原始问题.
在查看asyncore模块的源代码时,我遇到了这种方法.我会在没有上下文的情况下将它包含在内,因为它似乎非常自包含:
def initiate_send(self):
num_sent = 0
num_sent = dispatcher.send(self, self.out_buffer[:512])
self.out_buffer = self.out_buffer[num_sent:]
Run Code Online (Sandbox Code Playgroud)
我的问题:为什么num_sent首先设置为0,但然后立即再次设置为另一个值?
如果我在python源代码中的任何地方找到它,我会说这行代码是多余的.有什么意义吗,还是死代码?
我很想知道下面的代码是如何工作的.它来自http://docs.python.org/library/itertools.html#itertools.izip_longest,并且是izip_longest迭代器的纯python等价物.我对哨兵功能特别神秘,它是如何工作的?
def izip_longest(*args, **kwds):
# izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
fillvalue = kwds.get('fillvalue')
def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
yield counter() # yields the fillvalue, or raises IndexError
fillers = repeat(fillvalue)
iters = [chain(it, sentinel(), fillers) for it in args]
try:
for tup in izip(*iters):
yield tup
except IndexError:
pass
Run Code Online (Sandbox Code Playgroud) 第17.1.4.2节:替换 python子进程模块的shell管道表示要替换
output=`dmesg | grep hda`
Run Code Online (Sandbox Code Playgroud)
同
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
Run Code Online (Sandbox Code Playgroud)
对第三行的评论解释了为什么调用close函数,而不是为什么它有意义.对我来说,它没有.调用通信方法之前是否会关闭p1.stdout以防止通过管道发送任何输出?(显然它不会,我试图运行代码,它运行正常).为什么有必要调用close来使p1接收SIGPIPE?什么样的亲密关闭?究竟是什么关闭?
请考虑这是一个学术问题,除了更好地理解这些事情之外我不想做任何事情.