Почему что не так с этим dict преобразованием объекта результата лямбда-выражения?

Я чувствовал себя самодовольным, думая, что у меня было лучшее лямбда-выражение во вселенной, готовое вернуть всю необходимую информацию о сети, когда-либо нужную, используя python и netiface

>>> 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'>

так что же испортило мой актерский состав обратно в словарь?

1 ответ

Решение

Когда дан словарь в качестве входных данных, filter будет только повторять и возвращать ключи из этого словаря.

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

Таким образом, вы вводите только последовательность отфильтрованных ключей в новый dict, а не пары ключ-значение. Вы можете исправить это так: Обратите внимание на вызов 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()]
Другие вопросы по тегам