Python双向映射

时间:2012-02-14 19:29:12

标签: python mapping

我不确定该怎么称呼我正在寻找的东西;所以,如果我没有在其他地方找到这个问题,我道歉。简而言之,我正在编写将直接与Linux内核连接的python代码。它很容易从包含头文件中获取所需的值并将它们写入我的源代码:

IFA_UNSPEC     =  0
IFA_ADDRESS    =  1
IFA_LOCAL      =  2
IFA_LABEL      =  3
IFA_BROADCAST  =  4
IFA_ANYCAST    =  5
IFA_CACHEINFO  =  6
IFA_MULTICAST  =  7

在构造要发送到内核的结构时,很容易使用这些值。但是,它们几乎无助于解析内核响应中的值。

如果我将值放入dict中,我将必须扫描dict中的所有值,以便从我假设的内核中查找每个结构中每个项的键。必须有一种更简单,更有效的方式。

你会怎么做? (如果有问题,请随时重新提出问题)

3 个答案:

答案 0 :(得分:9)

如果你想使用两个dicts,你可以尝试这个来创建倒置字典:

b = {v: k for k, v in a.iteritems()}

答案 1 :(得分:2)

您的解决方案会为重复的人创建文件留下大量工作。这是一个错误的来源(你实际上必须写三次每个名字)。如果您有一个文件,您需要不时更新这些文件(例如,当新的内核版本发布时),您注定迟早会包含错误。实际上,这只是一个很长的说法,你的解决方案违反了DRY

我会将你的解决方案改为:

IFA_UNSPEC     =  0
IFA_ADDRESS    =  1
IFA_LOCAL      =  2
IFA_LABEL      =  3
IFA_BROADCAST  =  4
IFA_ANYCAST    =  5
IFA_CACHEINFO  =  6
IFA_MULTICAST  =  7
__IFA_MAX      =  8

values = {globals()[x]:x for x in dir() if x.startswith('IFA_') or x.startswith('__IFA_')}

这是values dict自动生成的。根据该文件中的其他内容,您可能希望(或必须)更改if语句中的条件。也许类似以下内容。该版本将不再需要在if语句中列出前缀,但如果文件中有其他内容则会失败。

values = {globals()[x]:x for x in dir() if not x.endswith('__')}

你当然可以做一些更复杂的事情,例如:检查意外重复的值。

答案 2 :(得分:1)

我最终做的是在模块中保留常量值并创建一个字典。模块是ip_addr.py(值来自linux / if_addr.h),因此在构造结构以发送到内核时,我可以使用if_addr.IFA_LABEL并使用if_addr.values[2]解析响应。我希望这是最直接的,所以当我不得不在一年内再看一遍这很容易理解:p

IFA_UNSPEC     =  0
IFA_ADDRESS    =  1
IFA_LOCAL      =  2
IFA_LABEL      =  3
IFA_BROADCAST  =  4
IFA_ANYCAST    =  5
IFA_CACHEINFO  =  6
IFA_MULTICAST  =  7
__IFA_MAX      =  8

values = {
           IFA_UNSPEC    : 'IFA_UNSPEC',
           IFA_ADDRESS   : 'IFA_ADDRESS',
           IFA_LOCAL     : 'IFA_LOCAL',
           IFA_LABEL     : 'IFA_LABEL',
           IFA_BROADCAST : 'IFA_BROADCAST',
           IFA_ANYCAST   : 'IFA_ANYCAST',
           IFA_CACHEINFO : 'IFA_CACHEINFO',
           IFA_MULTICAST : 'IFA_MULTICAST',
           __IFA_MAX     : '__IFA_MAX'
         }