How to generalize this for loop for any lenght? - python

I want to generalize this in python for any "pos" length
for a in range(pos[0]):
for b in range(pos[1]):
for c in range(pos[2]):
for d in range(pos[3]):
for e in range(pos[4]):
for f in range(pos[5]):
neighbours.append([a, b, c, d, e, f])
I want to gather all the neighbours of my position in 6 dimensions. Neighbours are all combinations of x-1, x and x+1 for all coordinates. So I have to gather 3^dim -1 neighbours. pos is a {dim} length list with positions for all coordinatess. dx is discretization length. As you can see all loops are the same except for an increasing index in pos, so I want to generalize that, if possible.
for a in range(pos[0]- self.dx, pos[0]+2*self.dx, self.dx):
for b in range(pos[1]- self.dx, pos[1]+2*self.dx, self.dx):
for c in range(pos[2]- self.dx, pos[2]+2*self.dx, self.dx):
for d in range(pos[3]- self.dx, pos[3]+2*self.dx, self.dx):
for e in range(pos[4]- self.dx, pos[4]+2*self.dx, self.dx):
for f in range(pos[5]- self.dx, pos[5]+2*self.dx, self.dx):
neighbours.append([a, b, c, d, e, f])

You can solve it easily using recursion:
def combinations(pos, acc=[[]] * 3):
if len(pos) == 0:
return a Cloud
Amazon announced a $250 million venture fund to invest in Indian startups cc
else:
return combinations(pos[1:],
acc = \
[x + [y] for x in acc for y in pos[0]])
Test it by:
combinations([['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h']])
Which gives:
[['a', 'd', 'f'],
['a', 'd', 'g'],
['a', 'd', 'h'],
['a', 'e', 'f'],
['a', 'e', 'g'],
['a', 'e', 'h'],
['b', 'd', 'f'],
['b', 'd', 'g'],
...
['a', 'd', 'f'],
['a', 'd', 'g'],
['a', 'd', 'h'],
['a', 'e', 'f'],
['a', 'e', 'g'],
['a', 'e', 'h'],
['b', 'd', 'f'],
['b', 'd', 'g'],
['b', 'd', 'h'],
['b', 'e', 'f'],
['b', 'e', 'g'],
['b', 'e', 'h'],
['c', 'd', 'f'],
['c', 'd', 'g'],
['c', 'd', 'h'],
['c', 'e', 'f'],
['c', 'e', 'g'],
['c', 'e', 'h']]
To remove duplicates, put a list(set()) around the result, or if you want to keep the order:
result_list_unique = []
for x in result_list:
if x not in result_list_unique:
result_list_unique.append(x)
and use result_list_unique

Related

Get combinations of list without replacement in Python

I have a list of people and I want to make all combinations of their teams (of 3) with each other.
list_of_ppl = ['A','B','C','D','E','F']
What i need is:
>>> [['A','B','C'],['D','E','F']]
>>> [['A','B','D'],['C','E','F']]
>>> [['A','B','E'],['C','D','F']]
>>> [['A','B','F'],['C','D','E']]
>>> [['A','C','E'],['B','D','F']]
>>> and so on...
Edit: The len(list_of_ppl) can be greater than 6 and can be a number that is not divisible by 3. I only want teams of 3
For eg:
list_of_ppl = ['A','B','C','D','E','F','G']
>>> [['A','B','C'],['D','E','F'],['G']]
>>> [['A','B','D'],['C','E','G'],['F']]
>>> [['A','B','D'],['C','F','G'],['E']]
>>> [['A','B','F'],['C','E','G'],['D']]
>>> [['A','E','G'],['B','D','F'],['C']]
>>> and so on...
You can use a recursive function to keep getting a combination of 3 from the remaining list of people until the list is exhausted:
from itertools import combinations
def get_teams(list_of_ppl, size=3):
if len(list_of_ppl) > size:
for team in combinations(list_of_ppl, size):
for teams in get_teams(list(set(list_of_ppl) - set(team))):
yield [list(team), *teams]
else:
yield [list_of_ppl]
for team in get_teams(list_of_ppl):
print(team)
so that with list_of_ppl = ['A','B','C','D','E','F'], this outputs:
[['A', 'B', 'C'], ['F', 'E', 'D']]
[['A', 'B', 'D'], ['C', 'F', 'E']]
[['A', 'B', 'E'], ['C', 'F', 'D']]
[['A', 'B', 'F'], ['C', 'E', 'D']]
[['A', 'C', 'D'], ['F', 'B', 'E']]
[['A', 'C', 'E'], ['F', 'B', 'D']]
[['A', 'C', 'F'], ['B', 'E', 'D']]
[['A', 'D', 'E'], ['C', 'B', 'F']]
[['A', 'D', 'F'], ['C', 'B', 'E']]
[['A', 'E', 'F'], ['C', 'B', 'D']]
[['B', 'C', 'D'], ['E', 'F', 'A']]
[['B', 'C', 'E'], ['F', 'A', 'D']]
[['B', 'C', 'F'], ['E', 'A', 'D']]
[['B', 'D', 'E'], ['C', 'F', 'A']]
[['B', 'D', 'F'], ['C', 'A', 'E']]
[['B', 'E', 'F'], ['C', 'A', 'D']]
[['C', 'D', 'E'], ['F', 'B', 'A']]
[['C', 'D', 'F'], ['E', 'B', 'A']]
[['C', 'E', 'F'], ['B', 'A', 'D']]
[['D', 'E', 'F'], ['C', 'B', 'A']]
or with a list_of_ppl whose length is not divisible by 3 such as list_of_ppl = ['A','B','C','D','E','F','G'], this outputs:
[['A', 'B', 'C'], ['E', 'G', 'F'], ['D']]
[['A', 'B', 'C'], ['E', 'G', 'D'], ['F']]
[['A', 'B', 'C'], ['E', 'F', 'D'], ['G']]
[['A', 'B', 'C'], ['G', 'F', 'D'], ['E']]
[['A', 'B', 'D'], ['E', 'C', 'G'], ['F']]
[['A', 'B', 'D'], ['E', 'C', 'F'], ['G']]
[['A', 'B', 'D'], ['E', 'G', 'F'], ['C']]
[['A', 'B', 'D'], ['C', 'G', 'F'], ['E']]
[['A', 'B', 'E'], ['C', 'G', 'F'], ['D']]
[['A', 'B', 'E'], ['C', 'G', 'D'], ['F']]
[['A', 'B', 'E'], ['C', 'F', 'D'], ['G']]
[['A', 'B', 'E'], ['G', 'F', 'D'], ['C']]
[['A', 'B', 'F'], ['E', 'C', 'G'], ['D']]
[['A', 'B', 'F'], ['E', 'C', 'D'], ['G']]
[['A', 'B', 'F'], ['E', 'G', 'D'], ['C']]
[['A', 'B', 'F'], ['C', 'G', 'D'], ['E']]
[['A', 'B', 'G'], ['E', 'C', 'F'], ['D']]
[['A', 'B', 'G'], ['E', 'C', 'D'], ['F']]
[['A', 'B', 'G'], ['E', 'F', 'D'], ['C']]
[['A', 'B', 'G'], ['C', 'F', 'D'], ['E']]
[['A', 'C', 'D'], ['B', 'E', 'G'], ['F']]
[['A', 'C', 'D'], ['B', 'E', 'F'], ['G']]
[['A', 'C', 'D'], ['B', 'G', 'F'], ['E']]
[['A', 'C', 'D'], ['E', 'G', 'F'], ['B']]
[['A', 'C', 'E'], ['B', 'G', 'F'], ['D']]
[['A', 'C', 'E'], ['B', 'G', 'D'], ['F']]
[['A', 'C', 'E'], ['B', 'F', 'D'], ['G']]
[['A', 'C', 'E'], ['G', 'F', 'D'], ['B']]
[['A', 'C', 'F'], ['B', 'E', 'G'], ['D']]
[['A', 'C', 'F'], ['B', 'E', 'D'], ['G']]
[['A', 'C', 'F'], ['B', 'G', 'D'], ['E']]
[['A', 'C', 'F'], ['E', 'G', 'D'], ['B']]
[['A', 'C', 'G'], ['B', 'E', 'F'], ['D']]
[['A', 'C', 'G'], ['B', 'E', 'D'], ['F']]
[['A', 'C', 'G'], ['B', 'F', 'D'], ['E']]
[['A', 'C', 'G'], ['E', 'F', 'D'], ['B']]
[['A', 'D', 'E'], ['B', 'C', 'G'], ['F']]
[['A', 'D', 'E'], ['B', 'C', 'F'], ['G']]
[['A', 'D', 'E'], ['B', 'G', 'F'], ['C']]
[['A', 'D', 'E'], ['C', 'G', 'F'], ['B']]
[['A', 'D', 'F'], ['B', 'E', 'C'], ['G']]
[['A', 'D', 'F'], ['B', 'E', 'G'], ['C']]
[['A', 'D', 'F'], ['B', 'C', 'G'], ['E']]
[['A', 'D', 'F'], ['E', 'C', 'G'], ['B']]
[['A', 'D', 'G'], ['B', 'E', 'C'], ['F']]
[['A', 'D', 'G'], ['B', 'E', 'F'], ['C']]
[['A', 'D', 'G'], ['B', 'C', 'F'], ['E']]
[['A', 'D', 'G'], ['E', 'C', 'F'], ['B']]
[['A', 'E', 'F'], ['B', 'C', 'G'], ['D']]
[['A', 'E', 'F'], ['B', 'C', 'D'], ['G']]
[['A', 'E', 'F'], ['B', 'G', 'D'], ['C']]
[['A', 'E', 'F'], ['C', 'G', 'D'], ['B']]
[['A', 'E', 'G'], ['B', 'C', 'F'], ['D']]
[['A', 'E', 'G'], ['B', 'C', 'D'], ['F']]
[['A', 'E', 'G'], ['B', 'F', 'D'], ['C']]
[['A', 'E', 'G'], ['C', 'F', 'D'], ['B']]
[['A', 'F', 'G'], ['B', 'E', 'C'], ['D']]
[['A', 'F', 'G'], ['B', 'E', 'D'], ['C']]
[['A', 'F', 'G'], ['B', 'C', 'D'], ['E']]
[['A', 'F', 'G'], ['E', 'C', 'D'], ['B']]
[['B', 'C', 'D'], ['E', 'A', 'G'], ['F']]
[['B', 'C', 'D'], ['E', 'A', 'F'], ['G']]
[['B', 'C', 'D'], ['E', 'G', 'F'], ['A']]
[['B', 'C', 'D'], ['A', 'G', 'F'], ['E']]
[['B', 'C', 'E'], ['A', 'G', 'F'], ['D']]
[['B', 'C', 'E'], ['A', 'G', 'D'], ['F']]
[['B', 'C', 'E'], ['A', 'F', 'D'], ['G']]
[['B', 'C', 'E'], ['G', 'F', 'D'], ['A']]
[['B', 'C', 'F'], ['E', 'A', 'G'], ['D']]
[['B', 'C', 'F'], ['E', 'A', 'D'], ['G']]
[['B', 'C', 'F'], ['E', 'G', 'D'], ['A']]
[['B', 'C', 'F'], ['A', 'G', 'D'], ['E']]
[['B', 'C', 'G'], ['E', 'A', 'F'], ['D']]
[['B', 'C', 'G'], ['E', 'A', 'D'], ['F']]
[['B', 'C', 'G'], ['E', 'F', 'D'], ['A']]
[['B', 'C', 'G'], ['A', 'F', 'D'], ['E']]
[['B', 'D', 'E'], ['C', 'A', 'G'], ['F']]
[['B', 'D', 'E'], ['C', 'A', 'F'], ['G']]
[['B', 'D', 'E'], ['C', 'G', 'F'], ['A']]
[['B', 'D', 'E'], ['A', 'G', 'F'], ['C']]
[['B', 'D', 'F'], ['E', 'C', 'A'], ['G']]
[['B', 'D', 'F'], ['E', 'C', 'G'], ['A']]
[['B', 'D', 'F'], ['E', 'A', 'G'], ['C']]
[['B', 'D', 'F'], ['C', 'A', 'G'], ['E']]
[['B', 'D', 'G'], ['E', 'C', 'A'], ['F']]
[['B', 'D', 'G'], ['E', 'C', 'F'], ['A']]
[['B', 'D', 'G'], ['E', 'A', 'F'], ['C']]
[['B', 'D', 'G'], ['C', 'A', 'F'], ['E']]
[['B', 'E', 'F'], ['C', 'A', 'G'], ['D']]
[['B', 'E', 'F'], ['C', 'A', 'D'], ['G']]
[['B', 'E', 'F'], ['C', 'G', 'D'], ['A']]
[['B', 'E', 'F'], ['A', 'G', 'D'], ['C']]
[['B', 'E', 'G'], ['C', 'A', 'F'], ['D']]
[['B', 'E', 'G'], ['C', 'A', 'D'], ['F']]
[['B', 'E', 'G'], ['C', 'F', 'D'], ['A']]
[['B', 'E', 'G'], ['A', 'F', 'D'], ['C']]
[['B', 'F', 'G'], ['E', 'C', 'A'], ['D']]
[['B', 'F', 'G'], ['E', 'C', 'D'], ['A']]
[['B', 'F', 'G'], ['E', 'A', 'D'], ['C']]
[['B', 'F', 'G'], ['C', 'A', 'D'], ['E']]
[['C', 'D', 'E'], ['B', 'A', 'G'], ['F']]
[['C', 'D', 'E'], ['B', 'A', 'F'], ['G']]
[['C', 'D', 'E'], ['B', 'G', 'F'], ['A']]
[['C', 'D', 'E'], ['A', 'G', 'F'], ['B']]
[['C', 'D', 'F'], ['B', 'E', 'A'], ['G']]
[['C', 'D', 'F'], ['B', 'E', 'G'], ['A']]
[['C', 'D', 'F'], ['B', 'A', 'G'], ['E']]
[['C', 'D', 'F'], ['E', 'A', 'G'], ['B']]
[['C', 'D', 'G'], ['B', 'E', 'A'], ['F']]
[['C', 'D', 'G'], ['B', 'E', 'F'], ['A']]
[['C', 'D', 'G'], ['B', 'A', 'F'], ['E']]
[['C', 'D', 'G'], ['E', 'A', 'F'], ['B']]
[['C', 'E', 'F'], ['B', 'A', 'G'], ['D']]
[['C', 'E', 'F'], ['B', 'A', 'D'], ['G']]
[['C', 'E', 'F'], ['B', 'G', 'D'], ['A']]
[['C', 'E', 'F'], ['A', 'G', 'D'], ['B']]
[['C', 'E', 'G'], ['B', 'A', 'F'], ['D']]
[['C', 'E', 'G'], ['B', 'A', 'D'], ['F']]
[['C', 'E', 'G'], ['B', 'F', 'D'], ['A']]
[['C', 'E', 'G'], ['A', 'F', 'D'], ['B']]
[['C', 'F', 'G'], ['B', 'E', 'A'], ['D']]
[['C', 'F', 'G'], ['B', 'E', 'D'], ['A']]
[['C', 'F', 'G'], ['B', 'A', 'D'], ['E']]
[['C', 'F', 'G'], ['E', 'A', 'D'], ['B']]
[['D', 'E', 'F'], ['B', 'C', 'A'], ['G']]
[['D', 'E', 'F'], ['B', 'C', 'G'], ['A']]
[['D', 'E', 'F'], ['B', 'A', 'G'], ['C']]
[['D', 'E', 'F'], ['C', 'A', 'G'], ['B']]
[['D', 'E', 'G'], ['B', 'C', 'A'], ['F']]
[['D', 'E', 'G'], ['B', 'C', 'F'], ['A']]
[['D', 'E', 'G'], ['B', 'A', 'F'], ['C']]
[['D', 'E', 'G'], ['C', 'A', 'F'], ['B']]
[['D', 'F', 'G'], ['B', 'E', 'C'], ['A']]
[['D', 'F', 'G'], ['B', 'E', 'A'], ['C']]
[['D', 'F', 'G'], ['B', 'C', 'A'], ['E']]
[['D', 'F', 'G'], ['E', 'C', 'A'], ['B']]
[['E', 'F', 'G'], ['B', 'C', 'A'], ['D']]
[['E', 'F', 'G'], ['B', 'C', 'D'], ['A']]
[['E', 'F', 'G'], ['B', 'A', 'D'], ['C']]
[['E', 'F', 'G'], ['C', 'A', 'D'], ['B']]
Use combinations from itertools:
from itertools import combinations
list(map(list,combinations(list_of_ppl,3)))
[['A', 'B', 'C'],
['A', 'B', 'D'],
['A', 'B', 'E'],
['A', 'B', 'F'],
['A', 'C', 'D'],
['A', 'C', 'E'],
['A', 'C', 'F'],
['A', 'D', 'E'],
['A', 'D', 'F'],
['A', 'E', 'F'],
['B', 'C', 'D'],
['B', 'C', 'E'],
['B', 'C', 'F'],
['B', 'D', 'E'],
['B', 'D', 'F'],
['B', 'E', 'F'],
['C', 'D', 'E'],
['C', 'D', 'F'],
['C', 'E', 'F'],
['D', 'E', 'F']]
Or:
l = list(map(list,combinations(list_of_ppl,3)))
list(map(list,zip(l[::2],l[::-1][::2])))
[[['A', 'B', 'C'], ['D', 'E', 'F']],
[['A', 'B', 'E'], ['C', 'D', 'F']],
[['A', 'C', 'D'], ['B', 'E', 'F']],
[['A', 'C', 'F'], ['B', 'D', 'E']],
[['A', 'D', 'F'], ['B', 'C', 'E']],
[['B', 'C', 'D'], ['A', 'E', 'F']],
[['B', 'C', 'F'], ['A', 'D', 'E']],
[['B', 'D', 'F'], ['A', 'C', 'E']],
[['C', 'D', 'E'], ['A', 'B', 'F']],
[['C', 'E', 'F'], ['A', 'B', 'D']]]
Or:
list(map(list,zip(l,l[::-1])))
[[['A', 'B', 'C'], ['D', 'E', 'F']],
[['A', 'B', 'D'], ['C', 'E', 'F']],
[['A', 'B', 'E'], ['C', 'D', 'F']],
[['A', 'B', 'F'], ['C', 'D', 'E']],
[['A', 'C', 'D'], ['B', 'E', 'F']],
[['A', 'C', 'E'], ['B', 'D', 'F']],
[['A', 'C', 'F'], ['B', 'D', 'E']],
[['A', 'D', 'E'], ['B', 'C', 'F']],
[['A', 'D', 'F'], ['B', 'C', 'E']],
[['A', 'E', 'F'], ['B', 'C', 'D']],
[['B', 'C', 'D'], ['A', 'E', 'F']],
[['B', 'C', 'E'], ['A', 'D', 'F']],
[['B', 'C', 'F'], ['A', 'D', 'E']],
[['B', 'D', 'E'], ['A', 'C', 'F']],
[['B', 'D', 'F'], ['A', 'C', 'E']],
[['B', 'E', 'F'], ['A', 'C', 'D']],
[['C', 'D', 'E'], ['A', 'B', 'F']],
[['C', 'D', 'F'], ['A', 'B', 'E']],
[['C', 'E', 'F'], ['A', 'B', 'D']],
[['D', 'E', 'F'], ['A', 'B', 'C']]]
for v in list(map(list,zip(l,l[::-1]))):
print(v)
[['A', 'B', 'C'], ['D', 'E', 'F']]
[['A', 'B', 'D'], ['C', 'E', 'F']]
[['A', 'B', 'E'], ['C', 'D', 'F']]
[['A', 'B', 'F'], ['C', 'D', 'E']]
[['A', 'C', 'D'], ['B', 'E', 'F']]
[['A', 'C', 'E'], ['B', 'D', 'F']]
[['A', 'C', 'F'], ['B', 'D', 'E']]
[['A', 'D', 'E'], ['B', 'C', 'F']]
[['A', 'D', 'F'], ['B', 'C', 'E']]
[['A', 'E', 'F'], ['B', 'C', 'D']]
[['B', 'C', 'D'], ['A', 'E', 'F']]
[['B', 'C', 'E'], ['A', 'D', 'F']]
[['B', 'C', 'F'], ['A', 'D', 'E']]
[['B', 'D', 'E'], ['A', 'C', 'F']]
[['B', 'D', 'F'], ['A', 'C', 'E']]
[['B', 'E', 'F'], ['A', 'C', 'D']]
[['C', 'D', 'E'], ['A', 'B', 'F']]
[['C', 'D', 'F'], ['A', 'B', 'E']]
[['C', 'E', 'F'], ['A', 'B', 'D']]
[['D', 'E', 'F'], ['A', 'B', 'C']]
the built-in itertools has a helper function for doing it.
itertools.combinations
see doc
itertools.combinations(iterable, r)
Return r length subsequences of elements from the input iterable.
Combinations are emitted in lexicographic sort order. So, if the input >iterable is sorted, the combination tuples will be produced in sorted order.
Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each combination.

remove list items from list of list in python

I have a list of characters:
Char_list = ['C', 'A', 'G']
and a list of lists:
List_List = [['A', 'C', 'T'], ['C', 'A', 'T', 'G'], ['A', 'C', 'G']]
I would like to remove each Char_list[i] from the list of corresponding index i in List_List.
Output must be as follows:
[['A','T'], ['C', 'T', 'G'], ['A', 'C']]
what I am trying is:
for i in range(len(Char_list)):
for j in range(len(List_List)):
if Char_list[i] in List_List[j]:
List_List[j].remove(Char_list[i])
print list_list
But from the above code each character is removed from all lists.
How can I remove Char_list[i] only from corresponding list in List_list?
Instead of using explicit indices, zip your two lists together, then apply a list comprehension to filter out the unwanted character for each position.
>>> char_list = ['C', 'A', 'G']
>>> list_list = [['A', 'C', 'T'], ['C','A', 'T', 'G'], ['A', 'C', 'G']]
>>> [[x for x in l if x != y] for l, y in zip(list_list, char_list)]
[['A', 'T'], ['C', 'T', 'G'], ['A', 'C']]
You may use enumerate with nested list comprehension expression as:
>>> char_list = ['C', 'A', 'G']
>>> nested_list = [['A', 'C', 'T'], ['C', 'A', 'T', 'G'], ['A', 'C', 'G']]
>>> [[j for j in i if j!=char_list[n]] for n, i in enumerate(nested_list)]
[['A', 'T'], ['C', 'T', 'G'], ['A', 'C']]
I also suggest you to take a look at PEP 8 - Naming Conventions. You should not be using capitalized first alphabet with the variable name.
Char_list = ['C', 'A', 'G']
List_List = [['A', 'C', 'T'], ['C', 'A', 'T', 'G'], ['A', 'C', 'G']]
for i in range(len(Char_list)):
List_List[i].remove(Char_list[i])
print(List_List)
OUTPUT
[['A', 'T'], ['C', 'T', 'G'], ['A', 'C']]
If the characters repeat in nested lists, Use this
Char_list = ['C', 'A', 'G']
List_List = [['A', 'C','C','C', 'T'], ['C', 'A', 'T', 'G'], ['A', 'C', 'G']]
for i in range(len(Char_list)):
for j in range(List_List[i].count(Char_list[i])):
List_List[i].remove(Char_list[i])
print(List_List)

Python 2d list sort by colum header

I have a 2d list:
['C', 'A', 'D', 'B'], #header row
['F', 'C', 'F', 'E'], #row 1
['F', 'E', 'F', 'F'], #row 2
['B', 'A', 'F', 'A'],
['A', 'F', 'C', 'E'],
['F', 'F', 'E', 'E'],
['C', 'E', 'F', 'C']
The first row in the list is the header row: C, A, D, B.
How can I change this so that the columns are in order so it will appear:
['A', 'B', 'C', 'D'], #header row
['C', 'E', 'F', 'F'], #row 1
['E', 'F', 'F', 'F'], #row 2
['A', 'A', 'B', 'F'],
['F', 'E', 'A', 'C'],
['F', 'E', 'F', 'E'],
['E', 'C', 'C', 'F']
I want the headers to be in order A,B,C,D but also move the columns underneath with the header
You can use sorted and zip, first create a list of your column with zip(*a) then sort it (based on first index) with sorted, and again convert to first state with zip and convert the indices to list with map :
>>> map(list,zip(*sorted(zip(*a))))
[['A', 'B', 'C', 'D'],
['C', 'E', 'F', 'F'],
['E', 'F', 'F', 'F'],
['A', 'A', 'B', 'F'],
['F', 'E', 'A', 'C'],
['F', 'E', 'F', 'E'],
['E', 'C', 'C', 'F']]
You could use numpy.
>>> import numpy as np
>>> data = np.array([['C', 'A', 'D', 'B'], #header row
... ['F', 'C', 'F', 'E'], #row 1
... ['F', 'E', 'F', 'F'], #row 2
... ['B', 'A', 'F', 'A'],
... ['A', 'F', 'C', 'E'],
... ['F', 'F', 'E', 'E'],
... ['C', 'E', 'F', 'C']])
>>> data[:,np.argsort(data[0])] # select sorted indices of first row as column indices.
array([['A', 'B', 'C', 'D'],
['C', 'E', 'F', 'F'],
['E', 'F', 'F', 'F'],
['A', 'A', 'B', 'F'],
['F', 'E', 'A', 'C'],
['F', 'E', 'F', 'E'],
['E', 'C', 'C', 'F']],
dtype='|S1')

Sorting a list in Python without repeat previous item

Well
I have a unique combination of elements (A B C D E F)
from itertools import combinations
data = ['A', 'B', 'C', 'D', 'E', 'F'];
comb = combinations(data, 2);
d = [];
for i in comb:
d.append([i[0], i[1]]);
print d
This returns to me:
[['A', 'B'],
['A', 'C'],
['A', 'D'],
['A', 'E'],
['A', 'F'],
['B', 'C'],
['B', 'D'],
['B', 'E'],
['B', 'F'],
['C', 'D'],
['C', 'E'],
['C', 'F'],
['D', 'E'],
['D', 'F'],
['E', 'F']]
The question is, how to sort this in a way that the line N do not repeat element [0] or element [1] of line (N-1)...in a simpler way:
AB (This line can have any element)
CD (This line can't have A or B)
EF (This line can't have C or D)
AC (This line can't have E or F)
...
mylist= [['A', 'B'],
['A', 'C'],
['A', 'D'],
['A', 'E'],
['A', 'F'],
['B', 'C'],
['B', 'D'],
['B', 'E'],
['B', 'F'],
['C', 'D'],
['C', 'E'],
['C', 'F'],
['D', 'E'],
['D', 'F'],
['E', 'F']]
a=mylist[:] #this used to assign all elements to a so u have ur mylist safe
b=[]
b.append(a[0]) #this appends the first list in the list
del a[0] #now deleting appended list
while len(a)>0:
for val,i in enumerate(a):# enumerte gives index and value of list
if len(set(b[len(b)-1]).intersection(set(i)))==0: # this checks intersection so that both list should not have same elements
b.append(a[val])
del a[val]
print b
#output [['A', 'B'], ['C', 'D'], ['E', 'F'], ['A', 'C'], ['B', 'D'], ['C', 'E'], ['D', 'F'], ['A', 'E'], ['B', 'C'], ['D', 'E'], ['A', 'F'], ['B', 'E'], ['C', 'F'], ['A', 'D'], ['B', 'F']]
Using the neighborhood generator from this answer you can get the previous, current and next element in your loop, so that you can compare them. Then you can do something like this
from itertools import combinations
# Credit to Markus Jarderot for this function
def neighborhood(iterable):
iterator = iter(iterable)
prev = None
item = iterator.next() # throws StopIteration if empty.
for next in iterator:
yield (prev,item,next)
prev = item
item = next
# this can be written like this also prev,item=item,next
yield (prev,item,None)
data = ['A', 'B', 'C', 'D', 'E', 'F'];
comb = combinations(data, 2);
d = [];
for prev, item, next in neighborhood(comb):
# If prev and item both exist and neither are in the last element in d
if prev and item and not any(x in d[-1] for x in item):
d.append([item[0], item[1]])
elif item and not prev: # For the first element
d.append([item[0], item[1]])
print d
This prints
[['A', 'B'],
['C', 'D'],
['E', 'F']]
I'm aware this is probably not 100% what you need, but it should be able to get you where you want

Grid Permutation Algorithm - Fixed Row Order

Imagine a 3x3 grid:
[A, B, %]
[C, %, D]
[E, F, G]
The percentages % stand for empty spaces/positions.
The rows can be moved like beads on a string, such that the permutations for the configurations for the first row could be any one of:
[A, B, %] or [A, %, B] or [%, A, B]
Similarly for the second row. The third row contains no empty slots and so cannot change.
I am trying to produce all possible grids, given the possible permutations of each row.
The output should produce the following grids:
[A, B, %] [A, B, %] [A, B, %]
[C, D, %] [C, %, D] [%, C, D]
[E, F, G] [E, F, G] [E, F, G]
[A, %, B] [A, %, B] [A, %, B]
[C, D, %] [C, %, D] [%, C, D]
[E, F, G] [E, F, G] [E, F, G]
[%, A, B] [%, A, B] [%, A, B]
[C, D, %] [C, %, D] [%, C, D]
[E, F, G] [E, F, G] [E, F, G]
I have tried a method of looking through each row and shifting the space left and right, then generating new grids off that and recursing. I keep all grids in a set and ensure I only produce positions which haven't already been examined to prevent infinite recursion.
However, my algorithm seems to be horrendously inefficient (~1s per permutation!!) and doesn't look very nice either. I was wondering if there was an eloquent way of doing this? In python in particular.
I have some vague ideas but I'm sure there is a way of doing this which is short and simple which I'm overlooking.
EDIT: 3x3 is just an example. Grid could be of any size and it's really the row combinations which matter. For example:
[A, %, C]
[D, E, %, G]
[H, I]
is also a valid grid.
EDIT 2: The letters must maintain their order. For example [A, %, B] != [B, %, A] and [B, A, %] isn't valid
First you have to get all desired permutations for each line. Then you calculate the cross product of all lines.
The permutations of a line can be simple calculated by having the letters [A,B,%] and varying the starting index:
import itertools
# Example: line = ['A','B','%']
def line_permutations(line):
if '%' not in line:
return [line]
line.remove('%') # use copy.copy if you don't want to modify your matrix here
return (line[:i] + ['%'] + line[i:] for i in range(len(line) + 1))
The cross product is easiest to achieve using itertools.product
matrix = [['A','B','%'], ['C', '%', 'D'], ['E', 'F', 'G']]
permutations = itertools.product(*[line_permutations(line) for line in matrix])
for p in permutations:
print(p)
This solution is optimal in memory and CPU requirements, because permutations are never recomputed.
Example output:
(['%', 'A', 'B'], ['%', 'C', 'D'], ['E', 'F', 'G'])
(['%', 'A', 'B'], ['C', '%', 'D'], ['E', 'F', 'G'])
(['%', 'A', 'B'], ['C', 'D', '%'], ['E', 'F', 'G'])
(['A', '%', 'B'], ['%', 'C', 'D'], ['E', 'F', 'G'])
(['A', '%', 'B'], ['C', '%', 'D'], ['E', 'F', 'G'])
(['A', '%', 'B'], ['C', 'D', '%'], ['E', 'F', 'G'])
(['A', 'B', '%'], ['%', 'C', 'D'], ['E', 'F', 'G'])
(['A', 'B', '%'], ['C', '%', 'D'], ['E', 'F', 'G'])
(['A', 'B', '%'], ['C', 'D', '%'], ['E', 'F', 'G'])
Define a function called cycle
>>> def cycle(lst):
while True:
lst=lst[1:]+lst[0:1] if '%' in lst else lst
yield lst
Given an iterator, this will generate and return a cyclic left shift.
Now you have to pass each of the rows in the grid to the cycle
generator for the total iteration matching the length of the row
Now use itertools.product to find all combinations of the generated
row cyclic combinations.
In case there is no empty slot, no cycle permutation is generated
The final result is as follows
>>> for g in list(itertools.product(*[[x for (x,y) in zip(cycle(row),
range(0,len(row) if '%' in row else 1))] for row in grid])):
for r in g:
print r
print "="*10
For your Grid, this will generate
['B', '%', 'A']
['%', 'D', 'C']
['E', 'F', 'G']
===============
['B', '%', 'A']
['D', 'C', '%']
['E', 'F', 'G']
===============
['B', '%', 'A']
['C', '%', 'D']
['E', 'F', 'G']
===============
['%', 'A', 'B']
['%', 'D', 'C']
['E', 'F', 'G']
===============
['%', 'A', 'B']
['D', 'C', '%']
['E', 'F', 'G']
===============
['%', 'A', 'B']
['C', '%', 'D']
['E', 'F', 'G']
===============
['A', 'B', '%']
['%', 'D', 'C']
['E', 'F', 'G']
===============
['A', 'B', '%']
['D', 'C', '%']
['E', 'F', 'G']
===============
['A', 'B', '%']
['C', '%', 'D']
['E', 'F', 'G']
===============
A naive implementation:
g=[['A', 'B', '%'],
['C', '%', 'D'],
['E', 'F', 'G']]
from collections import deque
from itertools import product
def rotations(it):
d = deque(it,len(it))
for i in xrange(len(it)):
d.rotate(1)
yield list(d)
for i in product(*[rotations(x) if '%' in x else [x] for x in g]):
print i
gives:
(['%', 'A', 'B'], ['D', 'C', '%'], ['E', 'F', 'G'])
(['%', 'A', 'B'], ['%', 'D', 'C'], ['E', 'F', 'G'])
(['%', 'A', 'B'], ['C', '%', 'D'], ['E', 'F', 'G'])
(['B', '%', 'A'], ['D', 'C', '%'], ['E', 'F', 'G'])
(['B', '%', 'A'], ['%', 'D', 'C'], ['E', 'F', 'G'])
(['B', '%', 'A'], ['C', '%', 'D'], ['E', 'F', 'G'])
(['A', 'B', '%'], ['D', 'C', '%'], ['E', 'F', 'G'])
(['A', 'B', '%'], ['%', 'D', 'C'], ['E', 'F', 'G'])
(['A', 'B', '%'], ['C', '%', 'D'], ['E', 'F', 'G'])
Here it is. Note that on one side this approach is less clean, but it allows you to compute the permutations of # len(matrix[0])-1 only once and use them as templates for the output.
from itertools import permutations,product
def charPermutation(matrix):
permutation_list=list(permutations(["%%"]+["%s"]*(len(matrix[0])-1))) #Compute once, use infinitely
perms={i:[] for i in range(len(matrix))}
for it,line in enumerate(matrix):
chars=list(set(line)-set(["%"]))
if sorted(line)==sorted(chars):
perms[it]+=["".join([str(i) for i in line])]
else:
for p in permutation_list:
perms[it]+=["".join(["".join(p) % tuple(chars)])]
perms[it]=list(set(perms[it]))
return product(*[[list(k) for k in i] for i in perms.values()])
g=[
["A", "B", "%"],
["C", "%", "D"],
["E", "F", "G"]]
for x in charPermutation(g):
print [i for i in x]
[['A', '%', 'B'], ['C', 'D', '%'], ['E', 'F', 'G']]
[['A', '%', 'B'], ['%', 'C', 'D'], ['E', 'F', 'G']]
[['A', '%', 'B'], ['C', '%', 'D'], ['E', 'F', 'G']]
[['%', 'A', 'B'], ['C', 'D', '%'], ['E', 'F', 'G']]
[['%', 'A', 'B'], ['%', 'C', 'D'], ['E', 'F', 'G']]
[['%', 'A', 'B'], ['C', '%', 'D'], ['E', 'F', 'G']]
[['A', 'B', '%'], ['C', 'D', '%'], ['E', 'F', 'G']]
[['A', 'B', '%'], ['%', 'C', 'D'], ['E', 'F', 'G']]
[['A', 'B', '%'], ['C', '%', 'D'], ['E', 'F', 'G']]

Categories

Resources