Python: Adding element to list while iterating

前端 未结 11 582
太阳男子
太阳男子 2020-12-02 15:37

I know that it is not allowed to remove elements while iterating a list, but is it allowed to add elements to a python list while iterating. Here is an example:



        
相关标签:
11条回答
  • 2020-12-02 15:44

    You could use the islice from itertools to create an iterator over a smaller portion of the list. Then you can append entries to the list without impacting the items you're iterating over:

    islice(myarr, 0, len(myarr)-1)
    

    Even better, you don't even have to iterate over all the elements. You can increment a step size.

    0 讨论(0)
  • 2020-12-02 15:45

    You can do this.

    bonus_rows = []
    for a in myarr:
      if somecond(a):
          bonus_rows.append(newObj())
    myarr.extend( bonus_rows )
    
    0 讨论(0)
  • 2020-12-02 15:45

    make copy of your original list, iterate over it, see the modified code below

    for a in myarr[:]:
          if somecond(a):
              myarr.append(newObj())
    
    0 讨论(0)
  • 2020-12-02 15:47

    Why don't you just do it the idiomatic C way? This ought to be bullet-proof, but it won't be fast. I'm pretty sure indexing into a list in Python walks the linked list, so this is a "Shlemiel the Painter" algorithm. But I tend not to worry about optimization until it becomes clear that a particular section of code is really a problem. First make it work; then worry about making it fast, if necessary.

    If you want to iterate over all the elements:

    i = 0  
    while i < len(some_list):  
      more_elements = do_something_with(some_list[i])  
      some_list.extend(more_elements)  
      i += 1  
    

    If you only want to iterate over the elements that were originally in the list:

    i = 0  
    original_len = len(some_list)  
    while i < original_len:  
      more_elements = do_something_with(some_list[i])  
      some_list.extend(more_elements)  
      i += 1
    
    0 讨论(0)
  • 2020-12-02 15:48

    I had a similar problem today. I had a list of items that needed checking; if the objects passed the check, they were added to a result list. If they didn't pass, I changed them a bit and if they might still work (size > 0 after the change), I'd add them on to the back of the list for rechecking.

    I went for a solution like

    items = [...what I want to check...]
    result = []
    while items:
        recheck_items = []
        for item in items:
            if check(item):
                result.append(item)
            else:
                item = change(item)  # Note that this always lowers the integer size(),
                                     # so no danger of an infinite loop
                if item.size() > 0:
                    recheck_items.append(item)
        items = recheck_items  # Let the loop restart with these, if any
    

    My list is effectively a queue, should probably have used some sort of queue. But my lists are small (like 10 items) and this works too.

    0 讨论(0)
  • 2020-12-02 15:48

    You can use an index and a while loop instead of a for loop if you want the loop to also loop over the elements that is added to the list during the loop:

    i = 0
    while i < len(myarr):
        a = myarr[i];
        i = i + 1;
        if somecond(a):
            myarr.append(newObj())
    
    0 讨论(0)
提交回复
热议问题