将变量传递给某些if语句(共享范围)

时间:2017-10-18 18:36:07

标签: python python-3.x if-statement

考虑以下代码:

def function(condition):

    if condition == 'condition1':
        print('No problem here')

    if condition == 'condition2':
        test = ['1','2','3','4']
        print(test)

    if condition == 'condition3':
       #doing something else using variable 'test'

是否可以在两个if语句之间共享静态列表?目前,我有两个工作思路,但两者都有其局限性

案例1:在函数开头声明静态列表

def function(condition):
    test = ['1','2','3','4']
    if condition == 'condition1':
        print('No problem here')

    if condition == 'condition2':
        print(test)

    if condition == 'condition3':
       #doing something else using variable 'test'

限制:这意味着每次拨打function时我都会创建列表,即使condition == 'condition1'

时我不需要它

案例2:在if语句

中声明静态列表
def function(condition):

    if condition == 'condition1':
        print('No problem here')

    if condition == 'condition2':
        test = ['1','2','3','4']
        print(test)

    if condition == 'condition3':
       test = ['1','2','3','4']
       #doing something else using variable 'test'

限制:在这种特殊情况下看起来并不是那么糟糕,但如果我的列表中有更多的嵌套列表数据,重复它会使代码维护变得更加困难,因为需要进行更改做了不止一次。

也许有一个简单的方法可以解决这个问题,但我正在思考整个问题,但正如我所说,这是我第一次看到这种情况。

5 个答案:

答案 0 :(得分:1)

创建此列表非常简单。您可能在发布问题上花费的资源多于使用最佳解决方案保存的资源。 :-)如果每个函数调用的列表都相同,那么你有几个不错的选择:

(1)您的案例1 是好的:它易于阅读且易于维护。如果您担心分配,请打开优化开关,让解释器意识到这是一个不变的分配。

(2)自己强制执行常量状态:在函数之前输入

test = ['1','2','3','4']

def function(condition):
    if condition ...

修改

有关详细信息,请参阅此answer

中的时间安排

答案 1 :(得分:1)

在调用lambda之前,不会评估a lambda expression的右侧。如果您不想重新计算列表,可以

$obj3 = (object)[];
$obj3->third = 3;

print_r($obj3);

// output
// stdClass Object
// (
//     [third] => 3
// )

我应该提一下,当我们谈论这个主题时,Python的def function(condition): getTestArray = lambda: ['1','2','3','4'] if condition == 'condition1': print('No problem here') if condition == 'condition2': test = getTestArray() print(test) if condition == 'condition3': test = getTestArray() #doing something else using variable 'test' 及其BDFL,Guido,有一段有趣的历史:https://www.quora.com/Why-did-Guido-van-Rossum-want-to-remove-lambda-from-Python-3/answer/Max-Fischer-10

答案 2 :(得分:0)

我讨厌条件。使用对象和多态性。这可能看起来更像是前期工作,但这种模式非常强大,可以学习:

class ProblemAbstract:
    @property
    def test_data(self):
        return [1, 2, 3, 4]

    def process(self):
        raise NotImplementedError("Need to implement 'process'")


class NullProblem(ProblemAbstract):
    def process(self):
        return None


class ProblemType1(ProblemAbstract):
    def process(self):
        return "Do something with: {}".format(self.test_data)


class ProblemType2(ProblemAbstract):
    def process(self):
        return "Do something else with: {}".format(self.test_data)


def function(condition):
    condition_matrix = {
                        'condition1': NullProblem,
                        'condition2': ProblemType1,
                        'condition3': ProblemType2,
                        }
    return condition_matrix[condition]().process()

if __name__ == "__main__":
    print(function('condition1'))
    print(function('condition2'))
    print(function('condition3'))

输出:

None
Do something with: [1, 2, 3, 4]
Do something else with: [1, 2, 3, 4]

答案 3 :(得分:0)

我最终使用了@wvxvw评论中的解决方案,而道具则归他所有。

我决定创建一个像这样的函数

def get_test():
    test = ['1','2','3','4']
    return test

def function(condition):

    if condition == 'condition1':
        print('No problem here')

    if condition == 'condition2':
        test = get_test()
        print(test)

    if condition == 'condition3':
        test= get_test()

其他答案很棒,但我并不总是同意选择不优化代码是最好的做事方式。也许我错了,这是个人的,但上面显示的代码在我看来是优化的,可读的和可维护的。特别是对于function将被呼叫数千次的情况。

修改

我做了一些时间确认答案。以下是使用的代码示例,这是我称之为 Case1

import time

def function(condition):
    test = ['1','2','3','4']
    if condition == 'condition1':
       pass

    if condition == 'condition2':
       pass

    if condition == 'condition3':
       pass

start_time = time.time()
num_iterations = 10000
for i in range(num_iterations):
    function('condition1')
    function('condition2')
    function('condition3')

print("Case1 for %d iterations" %(num_iterations))    
print("--- %s seconds ---" % (time.time() - start_time))

我在 case2 中遵循了与我的问题中 case2 相关的相同模式, case3 表示我的答案中使用的逻辑。如您所见,只有列表创建会影响测试的时间。

<强>结果

Case1 for 10000 iterations
--- 0.01559591293334961 seconds ---

Case2 for 10000 iterations
--- 0.015594244003295898 seconds ---

Case3 for 10000 iterations
--- 0.015636682510375977 seconds ---

Case1 for 1000000 iterations
--- 1.1179990768432617 seconds ---

Case2 for 1000000 iterations
--- 0.9396021366119385 seconds ---

Case3 for 1000000 iterations
--- 1.0606272220611572 seconds ---

<强>摘要

我们可以得出结论,所有方法实现效率几乎相同。即使纯粹的性能 Case2 似乎是最好的(当你考虑它时这是逻辑)。不过,我认为我们应该参考这个answer

答案 4 :(得分:0)

与@RobertB类似,但使用函数式编程:

from functools import partial

def condition1():
  print('Hello first case')

def condition2(test):
  print('Hello second case. Test var is: {0}'.format(test))

def condition3(test):
  print('Hello thrid case. Test var is: {0}'.format(test))

def function(condition):

  test = []

  if condition in ('condition2', 'condition3'):
    test = ['1','2','3','4']

  conditions = {
    'condition1': condition1,
    'condition2': partial(condition2, test),
    'condition3': partial(condition3, test)
  }

  action = conditions.get(condition, lambda: print(NotImplemented))
  action()

function('condition')
function('condition1')
function('condition2')
function('condition3')