从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_')]。

python——socket模块与列表映射的更多相关文章

  1. Python接口测试-模块引用与映射

    PyCharm中发现模块引用老是有各种问题 可以用映射来解决,例如需要调用登录模块里面的东西的时,可以这样处理: 登录模块:1-login.py import this import requests ...

  2. python - socket模块1

    1.使用生活中的接打电话,解释socket通信流程  2.根据上图,写出socket通信的伪代码 2.1.server端伪代码 #买手机   #买手机卡 #开机 #等待电话 #收消息 #发消息 #挂电 ...

  3. python --- socket模块详解

    socket常用功能函数: socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)                  ...

  4. 用python socket模块实现简单的文件下载

    server端: # ftp server端 import socket, os, time server = socket.socket() server.bind(("localhost ...

  5. 项目: 基于Python socket模块实现的简单 ftp 项目:

    需要 自己创建一个 info 文件 用来存储用户信息 服务器: import socket import pickle import struct import os import time ''.s ...

  6. Python socket 基础(Server) - Foundations of Python Socket

    Python socket 基础 Server - Foundations of Python Socket 通过 python socket 模块建立一个提供 TCP 链接服务的 server 可分 ...

  7. python基础===socket模块的讲解(转)

    一.网络知识的一些介绍 socket 是网络连接端点.例如当你的Web浏览器请求www.jb51.net上的主页时,你的Web浏览器创建一个socket并命令它去连接 www.jb51.net的Web ...

  8. Python中的socket 模块

    Python 提供了两个基本的 socket 模块.第一个是 Socket,它提供了标准的 BSD Sockets API.第二个是 SocketServer, 它提供了服务器中心类,可以简化网络服务 ...

  9. Python网络编程(2)——socket模块(2)

    目录: 1. 异常 2. 地址族 3. 套接字类型 4. 模块方法 5. Socket对象与实例方法 socket模块提供了Python中的低层网络连接接口,用于操作套接字操作. 异常 socket模 ...

随机推荐

  1. 使用kubeadm安装kubernetes1.12.1

    kubeadm是kubernetes官方用来自动化高效安装kubernetes的工具,手动安装,特别麻烦. 使用kubeadm安装无疑是一种不错的选择. 1.环境准备 1.1系统配置 系统是CentO ...

  2. eclipse 关键字高亮显示

    关键字高亮显示(变量.函数名……) Toggle Mark Occurrences  (Alt + Shift + O), 也可以在eclipse主界面的快捷工具栏:按下那个小黄蜡笔图标,来设置高亮显 ...

  3. 最小生成树的Kruskal算法

        库鲁斯卡尔(Kruskal)算法是一种按照连通网中边的权值递增的顺序构造最小生成树的方法.Kruskal算法的基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的 ...

  4. linux中Firefox浏览器 手动安装 flash

    打开firefox浏览器,当你打开有关音频或者视频的网站时候,会提示你安装 flash,可是,官网提示,需要手动安装. 1.先从提示的官网上下载好文件 “install_flash_player_11 ...

  5. A - Enterprising Escape 【BFS+优先队列+map】

    The Enterprise is surrounded by Klingons! Find the escape route that has the quickest exit time, and ...

  6. 几何+暴力【p1959】 遗址[NOI导刊2009普及(6)]

    题目描述--> P1959 遗址_NOI导刊2009普及(6) 普通方法分析: 因为题目要求是找最大正方形(如果是长方形更麻烦. 讲真,题目不难,耗时间! 根据题目要求,我们要找的是正方形. 我 ...

  7. 35、Django实战第35天:完善点击数/ 收藏数

    点击数--课程 当我们进入一个课程的详情页的时候,点击数+1 当我们点击“我要学习”的时候,该课程的学习人数+1 点击数--教师 当我们进入一个讲师的详情页的时候,点击数+1 点击数--机构 当我们进 ...

  8. 算法-基数排序(radix sort)

    本文由@呆代待殆原创,转载请注明出处. 简介:这个排序是原来用在卡片排序机上的一个算法,一般用来比较具有多对关键字域的记录,如日期(年月日),通过基数排序我们会依次对年月日这三个关键字进行排序,只要对 ...

  9. [BZOJ 3170] 松鼠聚会

    Link: BZOJ 3170 传送门 Solution: $Knowledge Point:$ 切比雪夫距离$DIST(a,b)=max\{ |X'_a-X'_b|,|Y'_a-Y'_b|\}$ 曼 ...

  10. httpclient4.3访问https

    1.创建一个访问https的工具类 package org.aaa.tool;import java.io.File; import java.io.IOException; import java. ...