Броски len с помощью 'dict_keyiterator' не имеют функции len () при расчете исходящих и входящих ребер в сети x - PullRequest
0 голосов
/ 02 декабря 2018

Я реализую скрипт манипулирования графиком, и я был озадачен следующей ошибкой:

Traceback (most recent call last):
  File ".....py", line 12, in <module>
    print(len(graph.predecessors(i)), len(graph.successors(i)))
>>TypeError: object of type 'dict_keyiterator' has no len()<<

Это код:

import networkx as nx

graph = nx.DiGraph()

for i in range(10):
  graph.add_node(i)

for i in range(9):
  graph.add_edge(i, i+1)

for i in range(10):
  print(len(graph.predecessors(i)), len(graph.successors(i)))

Что это за dict_keyiterator и какисправить мой код?Спасибо!

1 Ответ

0 голосов
/ 02 декабря 2018

Проблема была в конечном итоге исправлена ​​путем преобразования итератора в список:

print(len(list(graph.predecessors(i))), len(list(graph.successors(i))))

Как предложил Яким Пироженко, предложенный альтернативный подход считается более быстрым, поэтому я проверил:

def f1():
  for i in range(10):
    len(list(graph.predecessors(i)))

def f2():
  for i in range(10):
    sum(1 for _ in graph.predecessors(i))

print(timeit.timeit(f1, number=100000))
print(timeit.timeit(f2, number=100000))

Иполучил:

0.529827729
0.652576311

Очевидно, что len(list(...)) подход здесь быстрее.Я использовал: Python 3.7 в Windows 10.


После некоторых поисков я нашел вопрос с аналогичной проблемой и простым объяснением здесь :

В 2.x iter(some_dict) возвращает словарь-ключист (странный дефис).В 3.x это dict_keyiterator (нормальное подчеркивание).

Так что кажется, что прямое использование iter(d), где d - это dict, приводит к объекту типа dict_keyiterator в Python 3. Это один из 3 итераторов, заменяющих Python 2: d.viewkeys(), d.viewitems() и d.viewvalues():

Соответствующие итераторы, возвращаемые iter() в 3.x:dict_keyiterator, dict_itemiterator и dict_valueiterator.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...