【问题标题】:for loop based on dynamic list python基于动态列表python的for循环
【发布时间】:2017-06-04 01:43:36
【问题描述】:

编辑: 程序的期望行为是找到具有增加趋势的数字序列,所以我想从ks list 生成一个这样的列表: desiredList=[[97,122],[98,111],[98,101,103,103,104]]

我有以下内容,我的目标是根据列表的长度运行 for 循环,列表长度在 for 循环本身内部发生变化。 Python 仅考虑 for 循环之前的长度,当列表的长度在循环中更改时,它仍然采用循环之前的旧值。代码如下:

ks=[97,122,111,98,111,98,101,103,103,104,97]
splitLine=2
counter=[]
for i in range(0,len(ks)):
   a=ks[i:splitLine]
   while len(a)>1:
        for j in range(0,len(a)):
            m=j
            n=j+1
            if(a[m]-a[n]<=0):
                c=c+1
                k=splitLine+c-1
                a.append(ks[k]) #When append happens, the for loop still takes the older value of len(a) instead of new value
            else:
                a.pop(-1)
                counter.append(a)
                splitLine=splitLine+1
                a=[]
                break

【问题讨论】:

  • 您解释了 for 循环的行为。但是您要解决的问题陈述不清楚。请编辑问题以解释所需的行为。还要提到示例输入和所需的输出
  • 除了您声明的问题之外,您的代码中还有几个问题。 a[m]a[n] 是字符串,你首先在哪里定义 c
  • 你想做什么?在迭代时修改列表几乎总是一个坏主意
  • 我已经编辑了这个问题,希望现在更清楚了。

标签: python for-loop conditional


【解决方案1】:

快速解决循环问题的方法是将for 循环换成while 循环。改变这个:

for j in range(0,len(a)):
    # <loop contents>

到这里:

j = 0
while j < len(a):
    # <loop contents>
    j += 1

for 循环从range(Python 2 中的 list 和 Python 3 中的生成器对象)中获取 j 的值。这个range 是在for 循环第一次运行时计算出来的;之后无论你对a做什么,它都不会更新。

while 循环在这种情况下为您提供了更多控制权,因为您可以指定要退出循环的条件。

【讨论】:

    【解决方案2】:

    正如 Moinuddin 所说,我们并不清楚您问题的根源。但是,下面的代码显示了如何在列表长度变化时继续迭代列表:

    def iterate_for_static_list_length(l):
        for i in range(len(l)):
            yield i
            l.append(object())
    
    
    def iterate_for_dynamic_list_length(l):
        for i, _ in enumerate(l):
            yield i
            l.append(object())
    
    
    if __name__ == '__main__':
        l = [object()] * 3
    
        print('Static implementation')
        for value in iterate_for_static_list_length(l):
            input(value)
    
        print('\nDynamic implementation')
        for value in iterate_for_dynamic_list_length(l):
            input(value)
    

    输出

    Static implementation
    0
    1
    2
    
    Dynamic implementation
    0
    1
    2
    3
    4
    5
    6
    7
    8
    

    这个程序将永远持续下去。在您的代码中,我可以看到您有条件地附加到循环内的列表中,因此它似乎最终应该终止。

    【讨论】:

      【解决方案3】:

      对于它试图解决的问题,您的实现可能嵌套了太多循环。

      第一个实现包含错误。请参阅下面的修复。

      或许可以尝试以下方法:

      l = [97,122,111,98,111,98,101,103,103,104,97]
      out = []
      acc = []
      for v in l:
          if len(acc)==0 or v >= acc[-1]:
              acc.append(v)
          else:
              if len(acc) > 1:
                  out.append(acc)
              acc = [v]
      
      print(out)
      >>>[[97, 122], [98, 111], [98, 101, 103, 103, 104]]
      

      之前的代码很慢,可能会丢弃最后找到的片段。我在对其进行随机测试以尝试优化版本时发现了该错误。以下代码显示了修正后的原始代码和可以提高 30% 的优化版本。

      def original(l):
          out = []
          acc = []
          added = False
          for v in l:
              if len(acc)==0 or v >= acc[-1]:
                  acc.append(v)
              else:
                  added = False
                  acc = [v]
      
              if acc is not None and len(acc)>1 and not added:
                  added = True
                  out.append(acc)
          return out
      
      
      def optimized(l):
          out = []
      
          acc = None
          tmp = None
          deb_v = False
          for v in l:
              prev =  acc[-1] if (acc is not None and len(acc)) else tmp
              if prev is not None and v >= prev:
                  if tmp is not None:
                      acc = []
                      acc.append(tmp)
                      out.append(acc)
                      tmp = None
                  acc.append(v)
              else:
                  acc = None
                  tmp = v
          return out
      
      
      # The original test data
      l = [97,122,111,98,111,98,101,103,103,104,97]
      assert original(l) == optimized(l) == [[97,122],[98,111],[98,101,103,103,104]]
      
      # A list that triggered last-fragment-dropped error
      l = [57, 16, 6, 19, 40, 3, 4, 13, 2, 70, 85, 65, 32, 69, 54, 51, 95, 74, 92, 46, 45, 26, 0, 61, 99, 43, 67, 71, 97, 10, 18, 73, 88, 47, 33, 82, 25, 75, 93, 80, 23, 37, 87, 90, 49, 15, 35, 63, 17, 64, 5, 72, 89, 21, 50, 8, 41, 86, 31, 78, 52, 76, 56, 42, 77, 36, 11, 60, 39, 22, 68, 27, 24, 28, 59, 96, 29, 38, 12, 79, 53, 9, 83, 94, 34, 14, 7, 48, 30, 20, 66, 62, 91, 58, 81, 1, 98, 44, 55, 84]
      assert original(l) == optimized(l)
      
      # Random testing
      import random
      l = list(range(100))
      random.shuffle(l)
      assert original(l) == optimized(l)
      
      # Timing!
      import timeit
      
      print(timeit.timeit("original(l)", globals={"l":l, "original": original}))
      # 43.95869998800117
      
      print(timeit.timeit("optimized(l)", globals={"l":l, "optimized": optimized}))
      # 34.82134292599949
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-19
        • 2013-04-01
        • 2017-08-24
        • 1970-01-01
        • 1970-01-01
        • 2022-01-25
        • 1970-01-01
        相关资源
        最近更新 更多