zoukankan      html  css  js  c++  java
  • 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还是被调用了。



  • 相关阅读:
    容器网络(一)docker容器网络驱动
    双指针遍历/滑动窗口 —— 209_长度最小的子数组
    双指针遍历/滑动窗口 —— 121_买卖股票的最佳时机
    双指针遍历/滑动窗口 —— 42_接雨水
    双指针遍历/滑动窗口 —— 26_删除排序数组中的重复项
    双指针遍历/滑动窗口 —— 16_最接近的三数之和
    双指针遍历/滑动窗口 —— 15_三数之和
    双指针遍历/滑动窗口 —— 11_盛最多水的容器
    双指针遍历/滑动窗口 —— 3_无重复字符的最长子串
    链表操作 —— 206_反转链表
  • 原文地址:https://www.cnblogs.com/hust/p/2597095.html
Copyright © 2011-2022 走看看