В python igraph, атрибуты вершины и края могут быть любыми типами объектов python, например. списки, словари. Я создал атрибут вершины, где каждая вершина имеет значение списка:Как назначить значения для отдельных элементов атрибутов списка igraph python?
import igraph
g = igraph.Graph.Barabasi(10,5)
g.vs['foo'] = [[]]
Тогда у меня есть (пустые) списки для каждой вершины:
print g.vs['foo']
# [[], [], [], [], [], [], [], [], [], []]
Значение атрибутов для отдельных вершин может ссылочную два способа:
print g.vs[0]['foo']
# []
print g.vs['foo'][0]
# []
Если я хочу сделать значение присваивания, это может быть возможно, таким образом:
g.vs[0]['foo'] = ['bar']
g.vs['foo'][0] = ['bar']
В результате, как я ожидаю, вершина число 0 имеет значение ['bar']
, в то время как остальные вершины имеют свой атрибут неизменным:
print g.vs[0]['foo']
# ['bar']
print g.vs['foo']
# [['bar'], [], [], [], [], [], [], [], [], []]
Моя первая, незначительная проблема возникает здесь: присваивания со вторым способом ссылки (т.е. Имя атрибута> индекс вершины) не работает:
g.vs['foo'] = [[]]
g.vs['foo'][0] = ['bar']
print g.vs['foo'][0]
# []
print g.vs['foo']
# [[], [], [], [], [], [], [], [], [], []]
Но моя основная проблема заключается в том, что изменение списка одной вершины дает странные результаты:
g.vs['foo'] = [[]]
g.vs[0]['foo'].append('bar')
print g.vs['foo']
# [['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar']]
g.vs['foo'] = [[]]
g.vs[0]['foo'] += ['bar']
print g.vs['foo']
# [['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar']]
не только атрибут вершина с номером 0, но все атрибуты вершин были добавлены значение! Это не то, чего я ожидал бы. Я могу дать значение атрибуты отдельных вершин таким образом:
g.vs['foo'] = [[]]
g.vs[0]['foo'] = g.vs[0]['foo'] + ['bar']
print g.vs['foo']
# [['bar'], [], [], [], [], [], [], [], [], []]
Но не с append()
:
g.vs['foo'] = [[]]
g.vs[0]['foo'] = g.vs[0]['foo'].append('bar')
print g.vs['foo']
# [None, ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar'], ['bar']]
Это действительно удивительно, значение 0 стало None
, в то время как все остальные имеют список с добавленный элемент. Я думаю, что это поведение связано с тем, что свойства указателей в python. Если я инициализировать значение каждого в отдельности, все работает, как я ожидал бы интуитивно:
for v in g.vs:
v['foo'] = []
g.vs[0]['foo'].append('bar')
print g.vs['foo']
# [['bar'], [], [], [], [], [], [], [], [], []]
Так что рекомендуемый метод применить append()
на атрибуты списка вершин? В случае добавления вершин атрибуты инициализируются до None
. В этом случае пользователям необходимо написать настраиваемые вспомогательные функции, чтобы согласовать типы атрибутов? Должны ли мы полностью избежать инициализации атрибутов таким образом: g.vs['foo'] = [[]]
?
Благодарим вас за примеры! Это для меня полезно, и я должен быть более осторожным при написании кода на Python. – deeenes