小编Lau*_*low的帖子

如何在numpy中反转置换数组

给定自我索引(不确定这是否是正确的术语)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)

看起来很简单,但我想不出怎么做.我试过谷歌搜索,但没有找到任何相关的.

python algorithm numpy vectorization

25
推荐指数
3
解决办法
7146
查看次数

为什么python的subprocess.call是这样实现的?

子进程模块具有便捷功能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)

我确定这是有原因的.我错过了什么?

python subprocess

13
推荐指数
1
解决办法
3850
查看次数

python:只查找几个dicts的公共键值对:dict intersection

我在列表中有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,但我自己只会提出不优雅和/或低效的解决方案.建议?

python

13
推荐指数
2
解决办法
6002
查看次数

请解释argparse模块中代码片段背后的推理

我正在查看内置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)

python argparse

11
推荐指数
1
解决办法
223
查看次数

在生成器中使用上下文管理器是否有意义的方法?

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__可能无法运行.

python generator contextmanager

10
推荐指数
1
解决办法
1871
查看次数

如何在谓词为第一个False的位置将列表拆分为两个

我一直在想应该有这样的功能,但我已经找遍了可能的地方(谷歌,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

9
推荐指数
2
解决办法
753
查看次数

类似Python的数字类会记住算术运算吗?

我想知道是否存在允许我做这样的事情的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代码,同时根据需要计算变量,以便计算在上下文中.过了一会你就发现了两个问题:

  1. 变量和参数的数量使得本地人变得混乱,变量名称很难记住.您应该将它们分组到类别中以跟踪它们.
  2. 您有时需要重做相同的计算,该计算分布在最后几章和十几行中,其中一个或多个参数已更改.您应该找到一些方法来避免代码重复.

出于这个问题出现了原始问题.

python

9
推荐指数
3
解决办法
1175
查看次数

为什么在分配本地变量之前立即给它一个初始值?

在查看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源代码中的任何地方找到它,我会说这行代码是多余的.有什么意义吗,还是死代码

python

9
推荐指数
1
解决办法
135
查看次数

itertools中的izip_longest:这里发生了什么?

我很想知道下面的代码是如何工作的.它来自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)

python python-itertools

7
推荐指数
2
解决办法
5055
查看次数

从Python子进程模块解释示例管道

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?什么样的亲密关闭?究竟是什么关闭?

请考虑这是一个学术问题,除了更好地理解这些事情之外我不想做任何事情.

python subprocess

7
推荐指数
1
解决办法
3011
查看次数