什么是在循环中在两个函数之间交替的pythonic方法

时间:2016-07-14 08:32:28

标签: python

对我来说这似乎是一个简单的问题,但搜索没有产生任何用处。

我的代码如下:

    for key, v in enumerate(ranges):

        ### Used to switch between voltage steps
        second_iter = 0

        for step in v:

            ### Set voltage sources to differential voltages
            if second_iter == 0:
                self.tf.institf.dcm.vsource1(step)
                second_iter = 1
            elif second_iter == 1:
                self.tf.institf.dcm.vsource2(step)

            self.measure_something()

v是2元素列表。范围是v的列表。我想循环遍历每个v,但每次都使用不同函数中的第二个元素。

是否有一种pythonic方式来编写上面的代码?

编辑:为了澄清,我想在之后做一些单独的代码来测量某些东西。所以我不能同时设置这两个功能。

7 个答案:

答案 0 :(得分:7)

你的代码非常直观......这不足以做到这一点,而不会滥用循环吗?

vsource1 = self.tf.institf.dcm.vsource1
vsource2 = self.tf.institf.dcm.vsource2

for key, (v1, v2) in enumerate(ranges):

    vsource1(v1)
    # Do some other stuff

    vsource2(v2)
    # Do some other stuff  

或者,如果"东西"同样你可以使用这样的循环来避免重复自己:

vsource1 = self.tf.institf.dcm.vsource1
vsource2 = self.tf.institf.dcm.vsource2

funcs = (vsource1, vsource2)

for key, steps in enumerate(ranges):
    for func, step in zip(funcs, steps):
        func(step)
        # Do some other stuff

答案 1 :(得分:1)

我会这样做:

for key, v in enumerate(range(0, 100)):
     [fun_call1() if key % 2 else fun_call2()]

答案 2 :(得分:1)

这减少了代码量,并将每次迭代的条件评估需求减少到1。

for key, v in enumerate(ranges):

    if key % 2 == 0:
        self.tf.institf.dcm.vsource1(v[0])
    else:
        self.tf.institf.dcm.vsource2(v[1])

答案 3 :(得分:0)

如果v是2元素列表,我会这样写:

for key, (step1, step2) in enumerate(ranges):
    self.tf.institf.dcm.vsource1(step1)
    self.measure_something()

    self.tf.institf.dcm.vsource2(step2)
    self.measure_something()

Pythonic并不总是意味着使用最先进的函数来生成最短的代码。由于你的例子中v的固定长度,我会说上面的解决方案是最容易阅读的,因此是pythonic。

答案 4 :(得分:0)

简单索引到第二个列表可以帮助避免循环和second_iter变量

for key, v in enumerate(ranges):
    self.tf.institf.dcm.vsource1(v[0])
    self.measure_something()

    self.tf.institf.dcm.vsource2(v[1])
    self.measure_something()

答案 5 :(得分:0)

您可以使用itertools.cyclezip

from itertools import cycle

vsources = [self.tf.institf.dcm.vsource1, self.tf.institf.dcm.vsource2]


for key, v in enumerate(ranges):
    for (step, vsource) in zip(v, cycle(vsources)):
        ### Set voltage sources to differential voltages
        vsource(step)

修改:我现在意识到每个v中只有两个值,因此无需使用cycle。德尔甘的回答似乎很好地涵盖了这一点,所以我只是按原样离开,并按照他的回答。

答案 6 :(得分:0)

不是严格的pythonic,但您可以使用余数运算符在两个函数之间切换:

range1 = ranges[0::2]
range2 = ranges[1::2]

for step in range1: func1(step)
for step in range2: func2(step)

这不是DRY,但可能通过将对每个函数的所有调用分组来更好地利用缓存。将for step in ranges[0::2]: func1(step) for step in ranges[1::2]: func2(step) 切片到您需要的两个数组中,然后在子数组上调用该函数:

    $initArray = 
    array (
      'width_id' => 
        array (
          0 => string '8',
          1 => string '24'
        ),
      'profile_id' => 
        array (
          0 => string '8',
          1 => string '13'
        ),
      'diameter_id' => 
        array (
          0 => string '4',
          1 => string '13'
        ), 
      'speed_id' => 
        array (
          0 => string '6',
          1 => string '13' 
       ),
      'load_id' => 
        array (
          0 => string '12', 
          1 => string '31'
        )
    )

$newArray = Array();

foreach ($innitArray as $key => $value){
   $newArray[$key][0] = $innitArray[$key][$vallue][0];
   $newArray[$key][1] = $innitArray[$key][$vallue][1];
}

内联切片:

{{1}}