小编Sha*_*ank的帖子

为什么Python中的函数可以在封闭范围内打印变量但不能在赋值中使用它们?

如果我运行以下代码:

x = 1

class Incr:
    print(x)
    x = x + 1
    print(x)

print(x)
Run Code Online (Sandbox Code Playgroud)

它打印:

1
2
1
Run Code Online (Sandbox Code Playgroud)

没问题,这正是我的预期.如果我做以下事情:

x = 1

class Incr:
    global x
    print(x)
    x = x + 1
    print(x)

print(x)
Run Code Online (Sandbox Code Playgroud)

它打印:

1
2
2
Run Code Online (Sandbox Code Playgroud)

也是我所期待的.没有问题.

现在,如果我开始按如下方式创建增量函数:

x = 1

def incr():
    print(x)

incr()
Run Code Online (Sandbox Code Playgroud)

它按照我的预期打印1.我假设它这样做是因为它无法x在其本地范围内找到,因此它搜索其封闭范围并找到x它.到目前为止没有问题.

如果我这样做:

x = 1

def incr():
    print(x)
    x = x + 1

incr()
Run Code Online (Sandbox Code Playgroud)

这在回溯中给出了以下错误:

UnboundLocalError:赋值前引用的局部变量'x'.

为什么Python不只是搜索封闭空间,x因为它找不到x像我class Incr一样用于赋值的值?请注意,我不是在问这个功能如何工作.我知道如果我执行以下操作,该功能将起作用:

x = 1

def incr(): …
Run Code Online (Sandbox Code Playgroud)

python scope

25
推荐指数
2
解决办法
6229
查看次数

具有恰好k个反转的n元素排列的数量

我正在努力有效地解决SPOJ问题64:排列.

设A = [a1,a2,...,an]是整数1,2,...,n的排列.如果ai> aj,则一对索引(i,j),1 <= i <= j <= n,是置换A的反转.我们给出整数n> 0和k> = 0.包含正好k次反转的n元素排列的数量是多少?

例如,恰好1次反转的4元素排列的数量等于3.

为了使给定的示例更容易看到,这里有三个4元素排列,正好有1个反转:

(1, 2, 4, 3)
(1, 3, 2, 4)
(2, 1, 3, 4)
Run Code Online (Sandbox Code Playgroud)

在第一个排列中,4> 3且指数4小于3的指数.这是单个反转.由于置换只有一次反转,因此它是我们试图计算的排列之一.

对于任何给定的n个元素序列,排列的数量是阶乘(n).因此,如果我使用强力n 2方法计算每个排列的反转次数,然后检查它们是否等于k,则该问题的解决方案将具有时间复杂度O(n!*n 2).


以前的研究

这个问题的一个子问题以前问这里在计算器上.给出了使用合并排序的O(n log n)解决方案,其计算单个排列中的反转次数.但是,如果我使用该解决方案来计算每个排列的反转次数,我仍然会得到O(n!*n log n)的时间复杂度,在我看来这仍然很高.

之前在Stack Overflow上也提到了这个确切的问题,但它没有收到任何答案.


我的目标是避免迭代所有排列所带来的因子复杂性.理想情况下,我想要一个数学公式,为任何n和k产生答案,但我不确定是否存在.

如果没有数学公式来解决这个问题(我有点怀疑),那么我也看到人们提示有效的动态编程解决方案是可能的.使用DP或其他方法,我真的想制定一个比O(n!*n log n)更有效的解决方案,但我不确定从哪里开始.

欢迎任何提示,评论或建议.

编辑:我已经用DP方法回答了下面的问题来计算Mahonian数.

algorithm permutation dynamic-programming combinatorics discrete-mathematics

16
推荐指数
3
解决办法
1万
查看次数

在JavaScript中在数组中找到连续子阵列的优雅方法?

我想编写一个函数,从给定的起始索引中查找给定数组中的连续子数组,如果找到则返回数组中子数组的索引,如果找不到,则返回-1.这类似于String.indexOf,但是对于数组和子数组而不是字符串和子字符串.

这是我的工作代码:

var find_csa = function (arr, subarr, from_index) {
    if (typeof from_index === 'undefined') {
        from_index = 0;
    }

    var i, found, j;
    for (i = from_index; i < 1 + (arr.length - subarr.length); ++i) {
        found = true;
        for (j = 0; j < subarr.length; ++j) {
            if (arr[i + j] !== subarr[j]) {
                found = false;
                break;
            }
        }
        if (found) return i;
    }
    return -1;
};
Run Code Online (Sandbox Code Playgroud)

这些是我的测试和他们的期望值:

console.log(find_csa([1, 2, 3, 4, 5], [2, 3, …
Run Code Online (Sandbox Code Playgroud)

javascript arrays

12
推荐指数
2
解决办法
4254
查看次数

Python 3异常删除封闭范围内的变量,原因不明

我有以下代码:

def foo():
    e = None
    try:
        raise Exception('I wish you would except me for who I am.')
    except Exception as e:
        print(e)
    print(e)

foo()
Run Code Online (Sandbox Code Playgroud)

在Python 2.7中,它按预期运行并打印:

I wish you would except me for who I am.
I wish you would except me for who I am.
Run Code Online (Sandbox Code Playgroud)

但是在Python 3.x中,第一行是打印的,但第二行不是.它似乎删除了封闭范围中的变量,从最后一个print语句给出了以下回溯:

Traceback (most recent call last):
  File "python", line 9, in <module>
  File "python", line 7, in foo
UnboundLocalError: local variable 'e' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

几乎就像del eexcept块之后插入一个语句一样.这种行为有什么理由吗?我可以理解,如果Python开发人员想要除了块有自己的局部范围,而不是泄漏到周围的范围,但为什么必须删除先前分配的外部范围中的变量?

python exception-handling exception python-3.x

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

Python正则表达式:拆分模式匹配,这是一个空字符串

使用该re模块,似乎我无法拆分空字符串的模式匹配:

>>> re.split(r'(?<!foo)(?=bar)', 'foobarbarbazbar')
['foobarbarbazbar']
Run Code Online (Sandbox Code Playgroud)

换句话说,即使找到匹配项,如果它是空字符串,甚至re.split也不能拆分字符串.

这些文档re.split似乎支持我的结果.

对于这种特殊情况,"解决方法"很容易找到:

>>> re.sub(r'(?<!foo)(?=bar)', 'qux', 'foobarbarbazbar').split('qux')
['foobar', 'barbaz', 'bar']
Run Code Online (Sandbox Code Playgroud)

但这是一种容易出错的方法,因为那时我必须要注意已经包含我正在拆分的子字符串的字符串:

>>> re.sub(r'(?<!foo)(?=bar)', 'qux', 'foobarbarquxbar').split('qux')
['foobar', 'bar', '', 'bar']
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来分割与re模块的空模式匹配?另外,为什么re.split不允许我首先这样做呢?我知道其他分裂算法可以与正则表达式一起使用; 例如,我可以使用JavaScript的内置功能完成此操作String.prototype.split().

python regex string split

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

在Lua中快速实现队列?

我正在使用Lua进行游戏,我需要使用广度优先搜索来实现快速路径搜索算法,该算法找到敌人AI和玩家之间的最短路径.

我将同时使用此算法最多3个敌人,并且地图是基于2维拼图的迷宫.我已经实现了碰撞检测,所以现在剩下要做的就是让敌人以一种可以快速完成并且最好每个敌人每秒约80-90次的方式找到玩家的最短路径.

当我之前实现广度优先搜索时,我在C++中使用了一个队列.从我读到的关于Lua的内容来看,使用表的堆栈实现非常有效,因为在push()(AKA table.insert)和pop()(table.remove)操作之后不需要移动元素.但是,我认为在Lua中大型队列的效率非常低,因为如果要在表的索引1中插入/删除某些内容,则表中的所有其他元素必须向上或向下移动.

因此,我想问一些Lua经验丰富的简单问题.在这种语言中,最简单和/或最快的队列实现是什么?是否有可能在Lua中拥有一个快速队列,或者只是普遍接受Lua总是被迫"移位"所有元素以进行队列操作,例如pop()append()

编辑:据我所知,Lua表中"移位元素"的底层实现是用C语言编写的,因此非常优化.在开始编写简单的表实现之前,我只想知道是否有更好的队列选项.

queue lua breadth-first-search path-finding lua-table

8
推荐指数
1
解决办法
7549
查看次数

Java Generics Wildcard vs Typed Generics用法

我正在阅读Java教程中的以下部分:http://docs.oracle.com/javase/tutorial/java/generics/capture.html

它首先说下面的代码产生错误,因为捕获无法转换为Object,因此该set方法无法确认Object是否为capture#1类型:

import java.util.List;

public class WildcardError {

    void foo(List<?> i) {
        i.set(0, i.get(0));
    }
}
Run Code Online (Sandbox Code Playgroud)

有点理解这背后的原因.i.get返回一个Object,编译器无法确定该对象是否为capture#1类型,因此无法以类型安全的方式将其与第二个参数匹配.

然后,它建议使用以下代码使此方法有效:

public class WildcardFixed {

    void foo(List<?> i) {
        fooHelper(i);
    }


    // Helper method created so that the wildcard can be captured
    // through type inference.
    private <T> void fooHelper(List<T> l) {
        l.set(0, l.get(0));
    }

}
Run Code Online (Sandbox Code Playgroud)

有点理解为什么这段代码也适用,在这段代码中,l.get保证是T类型的,所以它可以作为T类型的参数传递.

我不明白为什么你不能只使用这样的方法,没有帮助:

class GenericsTest {
    static <K> void bar(List<K> l) {
        l.set(0, l.get(l.size() - 1));
    } …
Run Code Online (Sandbox Code Playgroud)

java generics

5
推荐指数
1
解决办法
187
查看次数

将函数参数打包到字典中 - 与**kwargs相反

我正在尝试做与**kwargs相反的事情,我不确定它是否可能.但是知道Python它可能是:-)我希望在我的方法中清楚地设计所有属性(用于自动完成,并且易于使用),我想把它们全部抓住,比如说一个字典,然后继续传递.

class Foo(object):
   def __init__(self, a=1, b=2):
      inputs = grab_function_inputs_somehow()
      self.bar(**inputs)

   def bar(self, *args, **kwargs):
      pass
Run Code Online (Sandbox Code Playgroud)

通常的做法是将每个输入分配给一个对象参数,但我不想对所有类都这样做.我希望有一种方法可以将它包装到可以继承的方法中.

python arguments argument-passing

4
推荐指数
1
解决办法
915
查看次数

更优雅/ Pythonic的方式打印元组元素?

我有一个函数,它返回一大组整数值作为元组.例如:

def solution():
    return 1, 2, 3, 4 #etc.
Run Code Online (Sandbox Code Playgroud)

我想优雅地打印没有元组表示的解决方案.(即数字周围的括号).

我尝试了以下两段代码.

print ' '.join(map(str, solution())) # prints 1 2 3 4
print ', '.join(map(str, solution())) # prints 1, 2, 3, 4
Run Code Online (Sandbox Code Playgroud)

他们都工作,但他们看起来有点难看,我想知道是否有更好的方法这样做.有没有办法"解包"元组参数并将它们传递给printPython 2.7.5中的语句?

我真的很想做这样的事情:

print(*solution()) # this is not valid syntax in Python but I wish it was
Run Code Online (Sandbox Code Playgroud)

有点像元组解包,所以它相当于:

print sol[0], sol[1], sol[2], sol[3] # etc.
Run Code Online (Sandbox Code Playgroud)

除了没有丑陋的索引.有没有办法做到这一点?

我知道这是一个愚蠢的问题,因为我只是想摆脱括号,但我只是想知道是否有一些我不知道的东西.

python python-2.7

2
推荐指数
1
解决办法
136
查看次数

Python列表附加时间

cat /proc/meminfo

MemTotal:3981272 kB

我在python中运行了这个简单的测试

#!/usr/bin/env python
import sys
num = int(sys.argv[1])
li = []
for i in xrange(num):
    li.append(i)


$ time ./listappend.py 1000000

real    0m0.342s
user    0m0.304s
sys 0m0.036s

$ time ./listappend.py 2000000

real    0m0.646s
user    0m0.556s
sys 0m0.084s

$ time ./listappend.py 4000000

real    0m1.254s
user    0m1.136s
sys 0m0.116s

$ time ./listappend.py 8000000

real    0m2.424s
user    0m2.176s
sys 0m0.236s

$ time ./listappend.py 16000000

real    0m4.832s
user    0m4.364s
sys 0m0.452s

$ time ./listappend.py 32000000

real    0m9.737s
user    0m8.637s
sys 0m1.028s …
Run Code Online (Sandbox Code Playgroud)

python performance

2
推荐指数
1
解决办法
460
查看次数