python dict2種遍歷方式及區別


對於python的dict數據類型常用for結合dict的items方法進行遍歷

for k,v in d.items():
	print k,v

 還有種遍歷方式

利用dict的popitem方法進行遍歷

while d:
	k,v=d.popitem()
	print k,v

 這2種方法主要區別是什么呢,采用第一種方式遍歷不會改變原變量,比如d={"a":1,"b":2,"c":3,"d":4}遍歷后d還是這個值,第二種遍歷后d={}

對於可能會發生變化的dict采用第二種方式較為安全,采用for來遍歷會產生不穩定的結果。

具體例子,tornado框架IOloop.py文件里有這么段代碼

def start(self):
    """Starts the I/O loop.
    The loop will run until one of the I/O handlers calls stop(), which
    will make the loop stop after the current event iteration completes.
    """
    self._running = True
    while True:
    [ ... ]
        if not self._running:
            break
        [ ... ]
        try:
            event_pairs = self._impl.poll(poll_timeout)
        except Exception, e:
            if e.args == (4, "Interrupted system call"):
                logging.warning("Interrupted system call", exc_info=1)
                continue
            else:
                raise
        # Pop one fd at a time from the set of pending fds and run
        # its handler. Since that handler may perform actions on
        # other file descriptors, there may be reentrant calls to
        # this IOLoop that update self._events
        self._events.update(event_pairs)
        while self._events:
            fd, events = self._events.popitem()
            try:
                self._handlers[fd](fd, events)
            except KeyboardInterrupt:
                raise
            except OSError, e:
                if e[0] == errno.EPIPE:
                    # Happens when the client closes the connection
                    pass
                else:
                    logging.error("Exception in I/O handler for fd %d",
                                  fd, exc_info=True)
            except:
                logging.error("Exception in I/O handler for fd %d",
                              fd, exc_info=True)

 

里邊是這么遍歷一個dict數據的

while self._events:
            fd, events = self._events.popitem()

為什么不采用下面這種常用遍歷方式呢
for  fd, events  in  self._events.items():
原因很簡單,在主循環期間,這個_events字典變量可能會被處理器所修改。比如remove_handler()處理器。這個方法把fd從_events字典中取出,
所以即使fd被選擇到了,它的處理器也不會被調用,如果使用for迭代循環_events,那么在迭代期間_events就不能被修改,否則會產生不可預計的錯誤,
比如,明明調用了 remove_handler()方法刪除了某個<fd, handler>鍵值對,但是該handler還是被調用了。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM