How to simultaneously iterate and modify list, set, etc?

前端 未结 3 1282
抹茶落季
抹茶落季 2020-12-22 08:46

In my program I have many lines where I need to both iterate over a something and modify it in that same for loop.

How

相关标签:
3条回答
  • 2020-12-22 08:59

    This is a conceptual misunderstanding.

    It is dangerous to modify the list itself from within the iteration, because of the way Python translates the loop to lower level code. This can cause unexpected side effects during the iteration, there's a good example here :

    https://unspecified.wordpress.com/2009/02/12/thou-shalt-not-modify-a-list-during-iteration/

    But modifying mutable objects stored in the list is acceptable, and common practice.

    I suspect that you're thinking that because the list is made up of those objects, that modifying those objects modifies the list. This is understandable - it's just not how it's normally thought of. If it helps, consider that the list only really contains references to those objects. When you modify the objects within the loop - you are merely using the list to modify the objects, not modifying the list itself.

    What you should not do is add or remove items from the list during the iteration.

    0 讨论(0)
  • 2020-12-22 09:04

    you could get index first

    idx = [ el_idx for el_idx, el in enumerate(theList) if el.IsSomething() ]
    [ theList[i].SetIt(False) for i in idx ]
    
    0 讨论(0)
  • 2020-12-22 09:13

    Your problem seems to be unclear to me. But if we talk about harmful of modifying list during a for loop iteration in Python. I can think about two scenarios.

    First, You modify some elements in list that suppose to be used on the next round of computation as its original value.

    e.g. You want to write a program that have such inputs and outputs like these.

    Input:

    [1, 2, 3, 4]
    

    Expected output:

    [1, 3, 6, 10] #[1, 1 + 2, 1 + 2 + 3, 1 + 2 + 3 + 4]
    

    But...you write a code in this way:

    #!/usr/bin/env python
    
    mylist = [1, 2, 3, 4]
    
    for idx, n in enumerate(mylist):
        mylist[idx] = sum(mylist[:idx + 1])
    print mylist
    

    Result is:

    [1, 3, 7, 15] # undesired result
    

    Second, you make some change on size of list during a for loop iteration.

    e.g. From python-delete-all-entries-of-a-value-in-list:

    >>> s=[1,4,1,4,1,4,1,1,0,1]
    >>> for i in s:
    ...   if i ==1: s.remove(i)
    ... 
    >>> s
    [4, 4, 4, 0, 1]
    

    The example shows the undesired result that raised from side-effect of changing size in list. This obviously shows you that for each loop in Python can not handle list with dynamic size in a proper way. Below, I show you some simple way to overcome this problem:

      #!/usr/bin/env python
    
      s=[1, 4, 1, 4, 1, 4, 1, 1, 0, 1]
      list_size=len(s)
      i=0
    
      while i!=list_size:
          if s[i]==1:
              del s[i]
              list_size=len(s)
          else:
              i=i + 1
    
      print s
    

    Result:

    [4, 4, 4, 0]
    

    Conclusion: It's definitely not harmful to modify any elements in list during a loop iteration, if you don't 1) make change on size of list 2) make some side-effect of computation by your own.

    0 讨论(0)
提交回复
热议问题