I'm beginner to programming and I'm new here, so hello!
I'm having a problem with nodes order in networkX.
This code:
letters = []
G = nx.Graph()
for i in range(nodesNum):
letter = ascii_lowercase[i]
letters.append(letter)
print letters
G.add_nodes_from(letters)
print "G.nodes = ", (G.nodes())
returns this:
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd', 'e', 'f']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
G.nodes = ['a', 'c', 'b', 'e', 'd', 'g', 'f', 'i', 'h', 'j']
While I would like to have it in normal (alphabetical) order.
Could anyone tell me what am I doing wrong?
The order is important to me, as later I'm asking user to tell me where the edges are.
Thanks in advance!
You can sort the nodes on output like this
print "G.nodes = ", sorted(G.nodes())
or similarly you can sort the edges like
print "G.edges = ", sorted(G.edges())
Aric's solution would do fine if you want to use this for printing only. However if you are going to use adjacent matrix for calculations and you want consistent matrices in different runs, you should do:
letters = []
G = nx.OrderedGraph()
for i in range(10):
letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'][i]
letters.append(letter)
print (letters)
G.add_nodes_from(letters)
print ("G.nodes = ", (G.nodes()))
which returns
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd', 'e', 'f']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
G.nodes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
Related
I have following sequence of data:
['A',
'A',
'A',
'A',
'A',
'A',
'A',
'D',
'D',
'D',
'D',
'D',
'D',
'A',
'A',
'A',
'A',
'A',
'D',
'D',
'D',
'D',
'D',
'D']
How would I be able to create subsequence (list of list) as an example:
[['A',
'A',
'A',
'A',
'A',
'A',
'A'],
['D',
'D',
'D',
'D',
'D',
'D'],
['A',
'A',
'A',
'A',
'A'], ['D',
'D',
'D',
'D', 'D', 'D']]
That is I want to create a sublist which accumulates the first encountered value (eg 'A' or 'D' and append that to sublist and continue until it arrives at a different alphabet. The second list contains the sequence of the letters that were different than the first sequence and appends as sublist. The process continues until the last element of the main list.
itertools.groupby is a good tool for this kind of tasks:
from itertools import groupby
lst = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'D', 'D', 'D', 'D', 'D', 'D', 'A', 'A', 'A', 'A', 'A', 'D', 'D', 'D', 'D', 'D', 'D']
output = [list(g) for _, g in groupby(lst)]
print(output)
# [['A', 'A', 'A', 'A', 'A', 'A', 'A'], ['D', 'D', 'D', 'D', 'D', 'D'], ['A', 'A', 'A', 'A', 'A'], ['D', 'D', 'D', 'D', 'D', 'D']]
Solution:
import itertools
lis = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'D', 'D', 'D', 'D', 'D', 'D', 'A', 'A', 'A', 'A', 'A', 'D', 'D', 'D', 'D', 'D', 'D']
print([list(x[1]) for x in itertools.groupby(lis)])
Output:
[['A', 'A', 'A', 'A', 'A', 'A', 'A'], ['D', 'D', 'D', 'D', 'D', 'D'], ['A', 'A', 'A', 'A', 'A'], ['D', 'D', 'D', 'D', 'D', 'D']]
I want to create all possible permutations for an array in which each element can only occur once, with constraints on the element array index position.
ID = ["A","B","C","D","E","F","G","H","I","J"]
I want to create all possible permutations of the original_array, however the positions of each element are restricted to index positions given by:
ID = ["A","B","C","D","E","F","G","H","I","J"]
Index_Options=[]
for i in range(len(ID)):
List1=[]
distance=3
value = i - distance
for j in range((int(distance)*2)):
if value < 0 or value > len(ID):
print("Disregard") #Outside acceptable distance range
else:
List1.append(value)
value=value+1
Index_Options.append(List1)
print(Index_Options)
#Index_Options gives the possible index positions for each element. ie "A" can occur in only index positions 0,1,2, "B" can occur in only index positions 0,1,2,3 ect.
I'm just struggling on how to then use this information to create all the output permutations.
Any help would be appreciated
You can use a recursive generator function to build the combinations. Instead of generating all possible permutations from ID and then filtering based on Index_Options, it is much more efficient to produce a cartesian product of ID by directly traversing Index_Options:
ID = ["A","B","C","D","E","F","G","H","I","J"]
def combos(d, c = [], s = []):
if not d:
yield c
else:
for i in filter(lambda x:x not in s and x < len(ID), d[0]):
yield from combos(d[1:], c=c+[ID[i]], s=s+[i])
print(list(combos(Index_Options)))
Output (first ten combinations produced):
[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'I'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'I', 'H', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'I', 'J', 'H'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'J', 'H', 'I'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'J', 'I', 'H'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G', 'I', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G', 'J', 'I'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'I', 'G', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'I', 'J', 'G']]
You can use itertools.permutations to create all the possible permutations and then create new list with a check if all the letters are in the correct position
permutations = [p for p in itertools.permutations(ID, len(ID)) if all(i in Index_Options[ID.index(x)] for i, x in enumerate(p))]
I have two lists:
a = ['E', 'E', 'E', 'E', 'E', 'E', 'E', 'C', 'C', 'C']
b = ['C', 'C', 'E', 'E', 'E', 'E', 'E', 'C', 'E', 'C']
And I want to subset these to get:
a = ['E', 'E', 'E', 'E', 'E', 'E', 'E']
b = ['C', 'C', 'E', 'E', 'E', 'E', 'E']
Such that I keep the 'E' from the first list, but get the respective positional values using indices from the second list b.
I tried to use:
a = [x for x in a if x == 'E']
b = [x for x in b if x == 'E']
But this doesn't keep the order/position, instead it extracts just E from list b.
use zip function to zip and then unzip like this
a = ['E', 'E', 'E', 'E', 'E', 'E', 'E', 'C', 'C', 'C']
b = ['C', 'C', 'E', 'E', 'E', 'E', 'E', 'C', 'E', 'C']
a, b = zip(*[(ai, bi) for ai, bi in zip(a,b) if ai=="E"])
print(a)
print(b)
Output
('E', 'E', 'E', 'E', 'E', 'E', 'E')
('C', 'C', 'E', 'E', 'E', 'E', 'E')
Simply with itertools.takewhile feature:
from itertools import takewhile
a = ['E', 'E', 'E', 'E', 'E', 'E', 'E', 'C', 'C', 'C']
b = ['C', 'C', 'E', 'E', 'E', 'E', 'E', 'C', 'E', 'C']
a_slice = list(takewhile(lambda x: x == 'E', a))
b_slice = b[:len(a_slice)]
print(a_slice) # ['E', 'E', 'E', 'E', 'E', 'E', 'E']
print(b_slice) # ['C', 'C', 'E', 'E', 'E', 'E', 'E']
Try this
a = [x for x in a if x == 'E']
indexes = [i for i, x in enumerate(a) if x == "E"]
b = [b[i] for i in indexes]
I have a list of lists containing unique strings and I want to produce an arbitrary number of different ways of sorting it. The list might look like the following:
list = [[a], [b,c], [d], [e,f,g]]
The order of the lists need to be the same but I want to shuffle the ordering within a list and then have them in a single list, e.g
list1 = [a,b,c,d,e,f,g]
list2 = [a,c,b,d,f,e,g]
...
...
listN = [a,c,b,d,f,g,e]
What is a good pythonic way of achieving this? I'm on python 2.7.
from itertools import permutations, product
L = [['a'], ['b','c'], ['d'], ['e', 'f', 'g']]
for l in product(*map(lambda l: permutations(l), L)):
print([item for s in l for item in s])
produces:
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'g', 'f']
['a', 'b', 'c', 'd', 'f', 'e', 'g']
['a', 'b', 'c', 'd', 'f', 'g', 'e']
['a', 'b', 'c', 'd', 'g', 'e', 'f']
['a', 'b', 'c', 'd', 'g', 'f', 'e']
['a', 'c', 'b', 'd', 'e', 'f', 'g']
['a', 'c', 'b', 'd', 'e', 'g', 'f']
['a', 'c', 'b', 'd', 'f', 'e', 'g']
['a', 'c', 'b', 'd', 'f', 'g', 'e']
['a', 'c', 'b', 'd', 'g', 'e', 'f']
['a', 'c', 'b', 'd', 'g', 'f', 'e']
You can do this by taking the Cartesian product of the permutations of the sub-lists, and then flattening the resulting nested tuples.
from itertools import permutations, product, chain
lst = [['a'], ['b', 'c'], ['d'], ['e', 'f', 'g']]
for t in product(*[permutations(u) for u in lst]):
print([*chain.from_iterable(t)])
output
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'g', 'f']
['a', 'b', 'c', 'd', 'f', 'e', 'g']
['a', 'b', 'c', 'd', 'f', 'g', 'e']
['a', 'b', 'c', 'd', 'g', 'e', 'f']
['a', 'b', 'c', 'd', 'g', 'f', 'e']
['a', 'c', 'b', 'd', 'e', 'f', 'g']
['a', 'c', 'b', 'd', 'e', 'g', 'f']
['a', 'c', 'b', 'd', 'f', 'e', 'g']
['a', 'c', 'b', 'd', 'f', 'g', 'e']
['a', 'c', 'b', 'd', 'g', 'e', 'f']
['a', 'c', 'b', 'd', 'g', 'f', 'e']
If you need to do this in Python 2, you can replace the print line with this:
print list(chain.from_iterable(t))
Here's a more compact version, inspired by ewcz's answer:
for t in product(*map(permutations, lst)):
print list(chain.from_iterable(t))
This might not be the most elegant solution, but I think it does what you want
from itertools import permutations
import numpy as np
def fac(n):
if n<=1:
return 1
else:
return n * fac(n-1)
lists = [['a'], ['b','c'], ['d'], ['e','f','g']]
combined = [[]]
for perm in [permutations(l,r=len(l)) for l in lists]:
expanded = []
for e in list(perm):
expanded += [list(l) + list(e) for l in combined]
combined = expanded
## check length
print np.prod(map(fac,map(len,lists))), len(combined)
print '\n'.join(map(str,combined))
You can flatten the list then simply generate its permutations:
from itertools import chain, permutations
li = [['a'], ['b','c'], ['d'], ['e','f','g']]
flattened = list(chain.from_iterable(li))
for perm in permutations(flattened, r=len(flattened)):
print(perm)
>> ('a', 'b', 'c', 'd', 'e', 'f', 'g')
('a', 'b', 'c', 'd', 'e', 'g', 'f')
('a', 'b', 'c', 'd', 'f', 'e', 'g')
('a', 'b', 'c', 'd', 'f', 'g', 'e')
('a', 'b', 'c', 'd', 'g', 'e', 'f')
('a', 'b', 'c', 'd', 'g', 'f', 'e')
('a', 'b', 'c', 'e', 'd', 'f', 'g')
('a', 'b', 'c', 'e', 'd', 'g', 'f')
('a', 'b', 'c', 'e', 'f', 'd', 'g')
...
...
...
from itertools import chain, permutations
your_list = [[a], [b,c], [d], [e,f,g]]
flattened = chain.from_iterable(your_list)
perms = permutations(flattened)
for perm in perms:
print perm
References:
permutations in Python 2
chain in Python 2
I have a matrix:
matrix = [['F', 'B', 'F', 'A', 'C', 'F'],
['D', 'E', 'B', 'E', 'B', 'E'],
['F', 'A', 'D', 'B', 'F', 'B'],
['B', 'E', 'F', 'B', 'D', 'D']]
I want to remove and collect the first two elements of each sub-list, and add them to a new list.
so far i have got:
while messagecypher:
for vector in messagecypher:
final.extend(vector[:2])
the problem is; the slice doesn't seem to remove the elements, and I end up with a huge list of repeated chars. I could use .pop(0) twice, but that isn't very clean.
NOTE: the reason i remove the elements is becuase i need to keep going over each vector until the matrix is empty
You can keep your slice and do:
final = []
for i in range(len(matrix)):
matrix[i], final = matrix[i][:2], final + matrix[i][2:]
Note that this simultaneously assigns the sliced list back to matrix and adds the sliced-off part to final.
Well you can use a list comprehension to get the thing done, but its perhaps counter-intuitive:
>>> matrix = [['F', 'B', 'F', 'A', 'C', 'F'],
['D', 'E', 'B', 'E', 'B', 'E'],
['F', 'A', 'D', 'B', 'F', 'B'],
['B', 'E', 'F', 'B', 'D', 'D']]
>>> while [] not in matrix: print([i for var in matrix for i in [var.pop(0), var.pop(0)]])
['F', 'B', 'D', 'E', 'F', 'A', 'B', 'E']
['F', 'A', 'B', 'E', 'D', 'B', 'F', 'B']
['C', 'F', 'B', 'E', 'F', 'B', 'D', 'D']
EDIT:
Using range makes the syntax look cleaner:
>>> matrix = [['C', 'B', 'B', 'D', 'F', 'B'], ['D', 'B', 'B', 'A', 'B', 'A'], ['B', 'D', 'E', 'F', 'C', 'B'], ['B', 'A', 'C', 'B', 'E', 'F']]
>>> while [] not in matrix: print([var.pop(0) for var in matrix for i in range(2)])
['C', 'B', 'D', 'B', 'B', 'D', 'B', 'A']
['B', 'D', 'B', 'A', 'E', 'F', 'C', 'B']
['F', 'B', 'B', 'A', 'C', 'B', 'E', 'F']
Deleting elements is not an efficient way to go about your task. It requires Python to perform a lot of unnecessary work shifting things around to fill the holes left by the deleted elements. Instead, just shift your slice over by two places each time through the loop:
final = []
for i in xrange(0, len(messagecypher[0]), 2):
for vector in messagecypher:
final.extend(vector[i:i+2])