Я работаю над проблемой пространственного анализа, используя Python 2.7. У меня есть словарь edges
, представляющий ребра на графике, где ключ — это edgeID, а значение — начальная/конечная точки:
{e1: [(12.8254, 55.3880), (12.8343, 55.3920)],
e2: [(12.8254, 55.3880), (12.8235, 55.3857)],
e3: [(12.2432, 57.1120), (12.2426, 57.1122)]}
И у меня есть еще один словарь nodes
, где ключ — это идентификатор узла, а значение — координаты узла:
{n14: (12.8254, 55.3880),
n15: (12.8340, 55.3883),
n16: (12.8235, 55.3857),
n17: (12.8343, 55.3920)}
Мне нужно получить список, который будет выглядеть так («n» и «e» в ключах только для иллюстрации этого вопроса, у меня там есть целые числа):
[(e1,n14,n17),(e2,n14,n16)..]
То есть я перебираю словарь ребер, беру каждый ключ, нахожу значение, существующее в словаре nodes
, и добавляю его в кортеж. Вот как я это делаю сейчас:
edgesList = []
for featureId in edges:
edgeFeatureId = [k for k, v in edges.iteritems() if k == featureId][0]
edgeStartPoint = [k for k, v in nodes.iteritems() if v == edges[featureId][0]][0]#start point
edgeEndPoint = [k for k, v in nodes.iteritems() if v == edges[featureId][1]][0]#end point
edgesList.append((edgeFeatureId,edgeStartPoint,edgeEndPoint))
Это работает, но очень медленно при работе с большими наборами данных (с 100 000 ребер и 90 000 узлов это занимает около 10 минут).
Я понял, как использовать понимание списка при получении каждого из элементов кортежа, но возможно ли объединить мои 3 понимания списка в одно, чтобы избежать повторения ребер с помощью цикла for
(если это ускорит процесс)?
Есть ли другой способ ускорить создание такого списка?
ОБНОВЛЕНИЕ
Как предложил Мартин, я перевернул свои узлы:
nodesDict = dict((v,k) for k,v in oldnodesDict.iteritems())
имея кортеж узловых координат в качестве ключа и nodeID в качестве значения. К сожалению, это не ускорило процесс поиска (вот обновленный код — я поменял местами k
и v
на edgeStartPoint
и edgeEndPoint
):
edgesList = []
for featureId in edges:
edgeFeatureId = [k for k, v in edges.iteritems() if k == featureId][0]
edgeStartPoint = [v for k, v in nodes.iteritems() if k == edges[featureId][0]][0]#start point
edgeEndPoint = [v for k, v in nodes.iteritems() if k == edges[featureId][1]][0]#end point
edgesList.append((edgeFeatureId,edgeStartPoint,edgeEndPoint))
edgesList
: docs.python.org/2/ library/collections.html#collections.deque Двухсторонние очереди поддерживают потокобезопасные, эффективно использующие память операции добавления и извлечения с любой стороны двухсторонней очереди с примерно одинаковой производительностью O(1) в любом направлении. - person donmarkusi   schedule 27.02.2015iteritems()
везде, точка словаря - это поиск по ключу, сiteritems()
у вас есть производительность O (N) при каждом поиске. Либо переупорядочите свои данные, чтобы разрешить поиск по ключу, либо переключитесь на структуру типа двоичного дерева поиска, которая, по крайней мере, даст Olog (n). - person user3467349   schedule 27.02.2015