Related
I have a list[(position,id)] from the user based on the ids it chooses which I collect in data
data[(position,id)] = [(1,0),(2,0),(7,3),(8,6),(3,11),(3,11),(4,0),(5,1),(5,1),(6,2),(9,5),(10,7),(15,0),(16,10),(11,0),(11,1),(12,15),(13,8),(13,8),(13,9),(14,9)]
There are some duplicate elements in the list which I sorted out using *set(list) command
listdata = data
res=[]
res = [*set(listdata)]
print(res)
I get the res list as follows:
output: res = [(11, 1), (13, 8), (6, 2), (4, 0), (16, 10), (11, 0), (2, 0), (5, 1), (10, 7), (7, 3), (9, 5), (15, 0), (13, 9), (14, 9), (8, 6), (12, 15), (1, 0), (3, 11)]
But what I want is only 16 elements in the list on first come basis with positions 1 to 16, if you see here I have got 2 entries with position 11 [(11,1),(11,0)] and position 13[(13,8),(13,9)]
Required output:
res=[(11, 1), (13, 8), (6, 2), (4, 0), (16, 10), (2, 0), (5, 1), (10, 7), (7, 3), (9, 5), (15, 0), (14, 9), (8, 6), (12, 15), (1, 0), (3, 11)]
Can anyone suggest alternate solution?
This should probably be done with a generator.
res = [(11, 1), (13, 8), (6, 2), (4, 0), (16, 10), (11, 0), (2, 0), (5, 1), (10, 7), (7, 3), (9, 5), (15, 0), (13, 9), (14, 9), (8, 6), (12, 15), (1, 0), (3, 11)]
def foo(_res, max_items):
keys = []
for k,v in _res:
if k not in keys:
yield (k,v)
keys.append(k)
if len(keys) > max_items:
return
print(list(foo(res, 16)))
output:
[(11, 1), (13, 8), (6, 2), (4, 0), (16, 10), (2, 0), (5, 1), (10, 7), (7, 3), (9, 5), (15, 0), (14, 9), (8, 6), (12, 15), (1, 0), (3, 11)]
you can use a map to record every position only once
data = [(1,0),(2,0),(7,3),(8,6),(3,11),(3,11),(4,0),(5,1),(5,1),(6,2),(9,5),(10,7),(15,0),(16,10),(11,0),(11,1),(12,15),(13,8),(13,8),(13,9),(14,9)]
bucket = {}
for d in data:
bucket[d[0]] = d[1]
print(list(bucket.items()))
output is:
[(1, 0), (2, 0), (7, 3), (8, 6), (3, 11), (4, 0), (5, 1), (6, 2), (9, 5), (10, 7), (15, 0), (16, 10), (11, 1), (12, 15), (13, 9), (14, 9)]
update:
I am sorry I missed the description: "But what I want is only 16 elements in the list on first come basis", my answer above keeps the later came value, if you want to keep the first came one, do something like this:
data = [(1,0),(2,0),(7,3),(8,6),(3,11),(3,11),(4,0),(5,1),(5,1),(6,2),(9,5),(10,7),(15,0),(16,10),(11,0),(11,1),(12,15),(13,8),(13,8),(13,9),(14,9)]
bucket = {}
for d in data:
if d[0] not in bucket:
# if you never seen it, keep it, else ingore it.
bucket[d[0]] = d[1]
print(list(bucket.items()))
Hello im working on random placement for units on my game but i'm getting a very strange behaviour that could not understand, sometimes the array element removed from the array befor on the loop get removed again even that elelement not been show on the array. Could someone plz explaim me.
func update_avaliable_positions(pos):
#remover posição das disponiveis
var mob_pos = tilemap.world_to_map(pos)
var index = avaliable_positions.find(mob_pos)
#avaliable_positions.erase(mob_pos)
avaliable_positions.remove(index)
print('erase: ', mob_pos)
walkable_map.set_cellv(mob_pos, -1)
func populate(total):
randomize()
for n in range(total):
print('mob: ', n)
print('avaliable: ', avaliable_positions)
var rand_pos = randi() % avaliable_positions.size() #walkable_map.get_used_cells().size()
var mob = MonsterDatabase.add_mob('orc')
mob.position = tilemap.map_to_world(walkable_map.avaliable_cells[rand_pos]) + tilemap.cell_size/2
mobs_list.add_child(mob)
update_avaliable_positions(mob.position - tilemap.cell_size/2)
yield(get_tree().create_timer(3), "timeout" )
the out put is this:
player
avaliable: [(0, 4), (1, 4), (2, 4), (3, 4), (12, 4), (13, 4), (14, 4), (15, 4), (2, 5), (13, 5), (2, 6), (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (9, 7), (10, 7), (11, 7), (12, 7), (13, 7), (14, 7), (15, 7)]
erase: (15, 4)
mob: 0
avaliable: [(0, 4), (1, 4), (2, 4), (3, 4), (12, 4), (13, 4), (14, 4), (2, 5), (13, 5), (2, 6), (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (9, 7), (10, 7), (11, 7), (12, 7), (13, 7), (14, 7), (15, 7)]
erase: (13, 7)
mob: 1
avaliable: [(0, 4), (1, 4), (2, 4), (3, 4), (12, 4), (13, 4), (14, 4), (2, 5), (13, 5), (2, 6), (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (9, 7), (10, 7), (11, 7), (12, 7), (14, 7), (15, 7)]
erase: (9, 7)
mob: 2
avaliable: [(0, 4), (1, 4), (2, 4), (3, 4), (12, 4), (13, 4), (14, 4), (2, 5), (13, 5), (2, 6), (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (10, 7), (11, 7), (12, 7), (14, 7), (15, 7)]
erase: (15, 4) ---> here we see that (15,4) dont exist between options before
mob: 3
avaliable: [(0, 4), (1, 4), (2, 4), (3, 4), (12, 4), (13, 4), (14, 4), (2, 5), (13, 5), (2, 6), (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (10, 7), (11, 7), (12, 7), (14, 7), (15, 7)]
erase: (2, 7)
mob: 4
avaliable: [(0, 4), (1, 4), (2, 4), (3, 4), (12, 4), (13, 4), (14, 4), (2, 5), (13, 5), (2, 6), (0, 7), (1, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7), (8, 7), (10, 7), (11, 7), (12, 7), (14, 7), (15, 7)]
erase: (2, 7) ---> here we see that (2,7) dont exist between options before
any help will be very much appreciated. Thank you in advance.
I don't know where the array walkable_map.avaliable_cells[rand_pos] comes from but if it is not updated at the same time as the avaliable_positions array, it will return positions already removed.
Change your code by mob.position = tilemap.map_to_world(avaliable_positions[rand_pos]) + tilemap.cell_size/2 and it should work.
I would also avoid conversion between map coordinates and world coordinates to retrieve elements in the avaliable_positions array. You should pass the rand_pos value directly when you call the update_avaliable_positions function so you don't have to look up again for the index of the element to remove.
I'm writing a function to get coordinates of neighbours of a certain cell in orthogonal coordinates based on coordinates of the selected cell. My code is:
def get_neighbours_coordinates (x, y):
neighbours = []
for temp_x in [x-1, x, x+1]:
# condition to drop the case, when cell has the same coordinates as treated
for temp_y in [y-1, y, y+1]:
if (temp_x != x) and (temp_y != y):
neighbours.append((temp_x, temp_y))
print (neighbours)
Then, if I'm calling it as (for a sake of example):
for i in range (10):
get_neighbours_coordinates(i, i)
It returns:
[(-1, -1), (-1, 1), (1, -1), (1, 1)]
[(0, 0), (0, 2), (2, 0), (2, 2)]
[(1, 1), (1, 3), (3, 1), (3, 3)]
[(2, 2), (2, 4), (4, 2), (4, 4)]
[(3, 3), (3, 5), (5, 3), (5, 5)]
[(4, 4), (4, 6), (6, 4), (6, 6)]
[(5, 5), (5, 7), (7, 5), (7, 7)]
[(6, 6), (6, 8), (8, 6), (8, 8)]
[(7, 7), (7, 9), (9, 7), (9, 9)]
[(8, 8), (8, 10), (10, 8), (10, 10)]
While it supposed to return:
[(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)]
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2), (3, 3)]
[(2, 2), (2, 3), (2, 4), (3, 2), (3, 4), (4, 2), (4, 3), (4, 4)]
[(3, 3), (3, 4), (3, 5), (4, 3), (4, 5), (5, 3), (5, 4), (5, 5)]
[(4, 4), (4, 5), (4, 6), (5, 4), (5, 6), (6, 4), (6, 5), (6, 6)]
[(5, 5), (5, 6), (5, 7), (6, 5), (6, 7), (7, 5), (7, 6), (7, 7)]
[(6, 6), (6, 7), (6, 8), (7, 6), (7, 8), (8, 6), (8, 7), (8, 8)]
[(7, 7), (7, 8), (7, 9), (8, 7), (8, 9), (9, 7), (9, 8), (9, 9)]
[(8, 8), (8, 9), (8, 10), (9, 8), (9, 10), (10, 8), (10, 9), (10, 10)]
It looks like and dropped all cases where at least one of the conditions is true, while it has to drop only case where both conditions are true.
What is wrong with my code?
P.S. If I replace and with or, the code returns the desired output.
Using Python 3.9 on Windows 10.
The results you are seeing are consistent with your Boolean logic. By saying and you are saying that you want to exclude both the entire row and column of the cell in question. The only cell you really want to exclude is the query cell itself.
That is, you want:
not (temp_x == x and temp_y == y)
which is the same as:
(temp_x != x) or (temp_y != y)
This logical equivalence is one of De Morgan's Laws.
I have graphs with parallels edges(more than one edges) as shown below
G=nx.read_edgelist('file.txt',create_using=nx.MultiGraph(), nodetype=int)
Example output
(1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4)
now here I want to create the co-occurrence matrix from this graph
example output
1 2 3 4
1 0 13 17 24
2 13 0
etc
How can i do so? Most of the solutions from stack overflow are for word co-occurrence
Any help will be much appreciated
You could use the Counter from the collections module:
from collections import Counter
G = ...
cocounts = Counter(list(G.edges()))
# Then just allocate a list (2x4) or something and create the matrix:
res = [[0 for c in range(4)] for r in range(2)]
for cocount, count in cocounts.items():
res[cocount[0]-1][cocount[1]-1] = count
I'm trying to convert .txt to .gpickle in order to obtain the nodes and edges in networkx. I used the following codes to do so:
M = open("data.txt", "r")
G=nx.path_graph(M)
>>> nx.write_gpickle(G,"data.gpickle")
>>> G=nx.read_gpickle("data.gpickle")
After looking up the nodes and edges:
G.nodes()
G.edges()
I got outputs such as NodeView(()) and EdgeView([]), which should contain numerical values in the brackets. I assume that G=nx.path_graph(M) is the problem since it worked fine when I tried using the example from the reference:
>>> G = nx.path_graph(4)
>>> nx.write_gpickle(G, "test.gpickle")
>>> G = nx.read_gpickle("test.gpickle")
What you have is a weighted adjacency matrix in data.txt, the example you are using is to create a path graph, which has nothing to do with the information in your data. In order to create the proper graph, networkx cannot read it directly with that format. However, you can use numpy or pandas to read data.txt and then convert it to a networkx graph.
See the following code to get your graph with numpy:
import numpy as np
import networkx as nx
numpy_array = np.genfromtxt('data.txt', delimiter='\t', dtype='float')
G = nx.from_numpy_array(numpy_array)
Now you will have
In [1]: G.nodes()
Out[1]: NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))
In [2]: G.edges()
Out[2]: EdgeView([(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (0, 11), (0, 12), (0, 13), (0, 14), (0, 15), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (1, 11), (1, 12), (1, 13), (1, 14), (1, 15), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (2, 11), (2, 12), (2, 13), (2, 14), (2, 15), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (3, 11), (3, 12), (3, 13), (3, 14), (3, 15), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (4, 11), (4, 12), (4, 13), (4, 14), (4, 15), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (5, 11), (5, 12), (5, 13), (5, 14), (5, 15), (6, 7), (6, 8), (6, 9), (6, 10), (6, 11), (6, 12), (6, 13), (6, 14), (6, 15), (7, 8), (7, 9), (7, 10), (7, 11), (7, 12), (7, 13), (7, 14), (7, 15), (8, 9), (8, 10), (8, 11), (8, 12), (8, 13), (8, 14), (8, 15), (9, 10), (9, 11), (9, 12), (9, 13), (9, 14), (9, 15), (10, 11), (10, 12), (10, 13), (10, 14), (10, 15), (11, 12), (11, 13), (11, 14), (11, 15), (12, 13), (12, 14), (12, 15), (13, 14), (13, 15), (14, 15)])
To save your graph with gpickle format you do:
nx.write_gpickle(G, 'my_graph.gpickle')
Now you should be able to read it with G = nx.read_gpickle('my_graph.gpickle').
Depend on your data, you may read them directly, using networkx read_edgelist function, then write it into a pickle using its Doc:
G = nx.read_edgelist('test.txt', delimiter='\t', data=[('weight', int)], create_using=nx.DiGraph())
nx.write_gpickle(G, "test.gpickle")