1

认为我拥有世界上最好的 lambda 表达式来返回使用 python 和 netifaces 所需的所有相关网络信息时感到自鸣得意

>>> list(map(lambda interface: (interface, dict(filter(lambda ifaddress: ifaddress in (netifaces.AF_INET, netifaces.AF_LINK), netifaces.ifaddresses(interface) )))  , netifaces.interfaces()))

但我得到了这个

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
TypeError: cannot convert dictionary update sequence element #0 to a sequence

缩小一点

>>>dict(filter(lambda ifaddress: ifaddress in (netifaces.AF_INET, netifaces.AF_LINK), netifaces.ifaddresses("eth0")))

问题出在哪里:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot convert dictionary update sequence element #0 to a  sequence

但是所以我可以将过滤器对象转换为列表

 >>> list(filter(lambda ifaddress: ifaddress in (netifaces.AF_INET, netifaces.AF_LINK), netifaces.ifaddresses("eth0")))
 [17, 2]

但是,这不是我想要的。我想要它实际上是什么:

>>> netifaces.ifaddresses("tun2")
{2: [{'addr': '64.73.0.0', 'netmask': '255.255.255.255', 'peer': '192.168.15.4'}]}
>>> type (netifaces.ifaddresses("eth0"))
<class 'dict'>

那么是什么让我的演员回到字典?

4

1 回答 1

2

当给定字典作为输入时,filter只会迭代并返回该字典中的

>>> filter(lambda x: x > 1, {1:2, 3:4, 5:6})
[3, 5]

因此,您只是将过滤后的键序列输入新字典,而不是键值对。您可以像这样修复它:注意调用items()以及内部如何lambda获取元组作为输入。

list(map(lambda interface: (interface, dict(filter(lambda tuple: tuple[0] in (netifaces.AF_INET, netifaces.AF_LINK), 
                                                   netifaces.ifaddresses(interface).items()))), 
         netifaces.interfaces()))

现在这不是很漂亮......我建议将您的代码更改为嵌套列表和字典理解:

[(interface, {ifaddress: value 
          for (ifaddress, value) in netifaces.ifaddresses(interface).items()
          if ifaddress in (netifaces.AF_INET, netifaces.AF_LINK)})
 for interface in netifaces.interfaces()]
于 2016-02-05T21:00:05.733 回答