zoukankan      html  css  js  c++  java
  • python——socket模块与列表映射

    从socket模块学习中的一段奇怪代码说起

    前言:在学习python标准库中的Socket模块中,发现了一段奇怪的代码。

    import socket
    
    def get_constants(prefix):
    
    dicts=dict((getattr(socket,n),n)
        for n in dir(socket)
        if n.startswith('IPPROTO_'))
    
    print (dicts)

    疑问:上述代码中的for..in..循环语句和if 语句都没有冒号结束。为什么?

    答案:因为上述“异常”语句产生了一个形如(value,name)的映射列表。

    首先我注意到for和if语句都在同一个括号内,也就说for和if语句都不是完整的语句块,而是某个对象/参数的一部分。

    该语句完整的样子如下:

    dicts=dict((getattr(socket,n),n) for n in dir(socket) if n.startswith('IPPROTO_'))

    因此,需要查询如何用dict()构造字典对象。

    help(dict)

     |  dict() -> new empty dictionary
     |  dict(mapping) -> new dictionary initialized from a mapping object's
     |      (key, value) pairs
     |  dict(iterable) -> new dictionary initialized as if via:
     |      d = {}
     |      for k, v in iterable:
     |          d[k] = v
     |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
     |      in the keyword argument list.  For example:  dict(one=1, two=2)

    并不是第一种情况(无参数)和第四种情况(name=value pairs)。

    第二种情况 :什么是mapping呢?

    dict(mapping)构造python字典构造函数,怎么传入这个mapping参数呢?Python下的mapping到底是什么呢?
    目前已知有三种方法传入mapping。

    一 、方法一,通过使用map函数
      def fmap(a, b):
              return (a, b)
      lik = range(1, 11)
      liv = list("abcdefghij")
      print map(fmap, lik, liv)
    运行结果如下
    [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f'), (7, 'g'), (8, 'h'), (9, 'i'), (10, 'j')]

     map函数的作用是:每次从可迭代对象(这里是列表lik和liv)取出一个元素值,经过fmap自定义函数的处理后作为新的(返回)列表的元素,故这个map函数的操作方式很像列表解析的概念。


     理解了map函数后,便可将返回值作为dict的传入参数了,从而得到一个字典。
      def fmap(a, b):
              return (a, b)
      lik = range(1, 11)
      liv = list("abcdefghij")
      lim = map(fmap, lik, liv)
      d = dict(lim)
      print d

            执行结果如下所示:
      {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j'}

    二、方法二 :通过zip函数

    k=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

    v=[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

    m=zip(k,v)

    dict(m)={'a': 11, 'c': 13, 'b': 12, 'e': 15, 'd': 14, 'g': 17, 'f': 16, 'i': 19, 'h': 18, 'j': 20}

    三、方法三 :通过使用列表映射

    列表映射是通过对列表的每个元素应用一个函数来转换数据。

    什么是列表映射?

    列表映射介绍

    >>> li = [1, 9, 8, 4]
    
    >>> [elem*2 for elem in li] 
    
    [2, 18, 16, 8]
    
    >>> li                      
    
    [1, 9, 8, 4]

    为了对这一点有一个感性认识,从右向左看它。 li 是一个将要映射的列表。Python循环遍历 li 一次一个元素,临时将每个元素的值赋给变量 elem

    然后Python使用函数 elem*2 ,接着将结果追加到返回列表中。

    注意列表映射不改变被映射的列表
    >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
    
    >>> params.keys()
    
    ['server', 'uid', 'database', 'pwd']
    
    >>> [k for k in params.keys()]                              1
    
    ['server', 'uid', 'database', 'pwd']
    
    >>> [params[k] for k in params.keys()]                      2
    
    ['mpilgrim', 'sa', 'master', 'secret']
    
    >>> ["%s=%s" % (k, params[k]) for k in params.keys()]       3
    
    ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
    >>> ["%s=%s" % (k, params[k]) for k in params.keys() if k.startswith('s')]

    ['server=mpilgrim']
    1 简单的列表映射举例。映射表达式刚好是元素自身,所以这个列表映射返回列表的原封不动的拷贝。它等于 params.keys(). 2 效难一点的映射。重复遍历 params.keys(),变量 k 按顺序赋与每个元素,映射表达式接收元素然后在字典 params 中查找相应的值。它等于 params.values()。 3 用一些简单的字符串格式化将前面两个例子合并起来 ,我们就得到一个键-值对列表。这个看上去有点象程序的输出,剩下的就只是将这个列表中的元素接起来形成一个字符串了。
     
       

    因此,对某种构造特殊的list可以调用dict(list)把list对象转换为dict对象。

    也许,这种特殊构造的list就是mapping。

    因此上述代码:

    dicts=dict((getattr(socket,n),n) for n in dir(socket) if n.startswith('IPPROTO_'))

    中的(getattr(socket,n),n) for n in dir(socket) if n.startswith('IPPROTO_')部分其实是产生一个list的代码。
    即[(getattr(socket,n),n) for n in dir(socket) if n.startswith('IPPROTO_')]。

  • 相关阅读:
    JavaScript 检测浏览器更多信息【每日一段代码66】
    JavaScript throw 声明【每日一段代码64】
    JavaScript 计时器2 【每日一段代码73】
    JavaScript 按钮动画【每日一段代码70】
    JavaScript 检测浏览器【每日一段代码67】
    JavaScript 使用计时事件制作的钟表 【每日一段代码76】
    一个实现恢复删除机制(do undo)的设计
    基于邻接表的广度优先搜索遍历
    HDU1045 Fire Net
    深度遍历
  • 原文地址:https://www.cnblogs.com/Simon-xm/p/3978225.html
Copyright © 2011-2022 走看看