I have a list B containing elements. I want to create all possible pairs using these elements as shown in the expected output. But I am getting an error. How do I fix it?
import numpy as np
import itertools
B=[ 1, 2, 5, 7, 10, 11]
combination=[]
for L in range(len(B) + 1):
for subset in itertools.combinations(B, L):
combination.append([list(sub) for sub in subset])
combination
The error is
in <listcomp>
combination.append([list(sub) for sub in subset])
TypeError: 'int' object is not iterable
The expected output is
[1,2],[1,5],[1,7],[1,10],[1,11],
[2,1],[2,5],[2,7],[2,10],[2,11],
[5,1],[5,2],[5,7],[5,10],[5,11],
[7,1],[7,2],[7,5],[7,10],[7,11],
[10,1],[10,2],[10,5],[10,7],[10,11],
[11,1],[11,2],[11,5],[11,7],[11,10]
What you are looking for is not combinations but permutations:
>>> list(itertools.permutations(B, 2))
[(1, 2),
(1, 5),
(1, 7),
(1, 10),
(1, 11),
(2, 1),
(2, 5),
(2, 7),
(2, 10),
(2, 11),
(5, 1),
(5, 2),
(5, 7),
(5, 10),
(5, 11),
(7, 1),
(7, 2),
(7, 5),
(7, 10),
(7, 11),
(10, 1),
(10, 2),
(10, 5),
(10, 7),
(10, 11),
(11, 1),
(11, 2),
(11, 5),
(11, 7),
(11, 10)]
To convert to a list:
# List comprehension
perm = [list(p) for p in itertools.permutations(B, 2)
# Functional programming
perm = list(map(list, itertools.permutations(B, 2)))
Beside the #Corralien answer which is the correct one, i am just correcting your solution to let you know that your solution can also be made to work just changing few things
Do not convert & iterate subset as it is already a list and its element is not iterable
Replace combinations with permutations
Add a condition to filter only two combinations as your code is producing permutation of N X N
Final version is following.
import numpy as np
import itertools
B=[ 1, 2, 5, 7, 10, 11]
combination=[]
for L in range(len(B) + 1):
for subset in itertools.permutations(B, L):
if len(subset) == 2:
combination.append(subset)
print(combination)
OUTPUT
[(1, 2), (1, 5), (1, 7), (1, 10), (1, 11), (2, 1), (2, 5), (2, 7), (2, 10), (2, 11), (5, 1), (5, 2), (5, 7), (5, 10), (5, 11), (7, 1), (7, 2), (7, 5), (7, 10), (7, 11), (10, 1), (10, 2), (10, 5), (10, 7), (10, 11), (11, 1), (11, 2), (11, 5), (11, 7), (11, 10)]
Related
I have a list,
selected=[[0,5,9,10,0],[0,2,4,7,8,0],[0,1,3,6,0]]
It's a route of 3 cars.I want to convert it below,
selected1=[(0,5),(5,9),(9,10),(10,0),(0,2),(2,4),(4,7),(7,8),(8,0),(0,1),(1,3),(3,6),(6,0)]
I can do reverse by using networkx library(selected1 to selected),but now i need selected to selected1.Thanks for everyone.
Using a list comprehension might do the work :
selected=[[0,5,9,10,0],[0,2,4,7,8,0],[0,1,3,6,0]]
selected1 = [(s[i], s[i+1]) for s in selected for i in range(len(s)-1)]
# [(0, 5), (5, 9), (9, 10), (10, 0), (0, 2), (2, 4), (4, 7), (7, 8), (8, 0), (0, 1), (1, 3), (3, 6), (6, 0)]
I have a list of lists of tuples. Each inner list contains 3 tuples, of 2 elements each:
[
[(3, 5), (4, 5), (4, 5)],
[(7, 13), (9, 13), (10, 13)],
[(5, 7), (6, 7), (7, 7)]
]
I need to get a single list of 3 tuples, summing all these elements "vertically", like this:
(3, 5), (4, 5), (4, 5)
+ + + + + +
(7, 13), (9, 13), (10, 13)
+ + + + + +
(5, 7), (6, 7), (7, 7)
|| || ||
[(15, 25), (19, 25), (21, 25)]
so, for example, the second tuple in the result list is given by the sums of the second tuples in the initial list
(4+9+6, 5+13+7) = (19, 25)
I'm trying with list/tuple comprehensions, but I'm getting a little lost with this.
You can use zip and sum for something a little longer, but without the heavyweight dependency on numpy if you aren't already using it.
>>> [tuple(sum(v) for v in zip(*t)) for t in zip(*x)]
[(15, 25), (19, 25), (21, 25)]
The outer zip pairs the corresponding tuples together; the inner zip pairs corresponding elements of those tuples together for addition.
You could do this pretty easily with numpy. Use sum on axis 0.
import numpy as np
l = [
[(3, 5), (4, 5), (4, 5)],
[(7, 13), (9, 13), (10, 13)],
[(5, 7), (6, 7), (7, 7)]
]
[tuple(x) for x in np.sum(l,0)]
Output
[(15, 25), (19, 25), (21, 25)]
You could do this with pure python code.
lst = [
[(3, 5), (4, 5), (4, 5)],
[(7, 13), (9, 13), (10, 13)],
[(5, 7), (6, 7), (7, 7)]
]
lst2 = []
for a in range(len(lst[0])):
l = []
for i in range(len(lst)):
l.append(lst[i][a])
lst2.append(l)
output = []
for a in lst2:
t = [0 for a in range(len(lst[0][0]))]
for i in range(len(a)):
for z in range(len(a[i])):
t[z]+= a[i][z]
output.append(tuple(t))
print(output)
if you change the list then its is works.
output
IN:
lst = [
[(3, 5), (4, 5), (4, 5)],
[(7, 13), (9, 13), (10, 13)],
[(5, 7), (6, 7), (7, 7)]
]
OUT:
[(15, 25), (19, 25), (21, 25)]
IN:
lst = [
[(3, 5,2), (4, 5,3), (4, 5,1)],
[(7, 13,1), (9, 13,3), (10, 13,3)],
[(5, 7,6), (6, 7,3), (7, 7,7)]
]
OUT:
[(15, 25, 9), (19, 25, 9), (21, 25, 11)]
data = [
[(3, 5), (4, 5), (4, 5)],
[(7, 13), (9, 13), (10, 13)],
[(5, 7), (6, 7), (7, 7)]
]
result = [tuple(sum(x) for x in zip(*t)) for t in zip(*data)]
print(result)
This is a one-liner, I don't think you can get more pythonic than this.
This question already has answers here:
Cartesian products of lists without duplicates
(2 answers)
Closed 3 years ago.
I want to create an iterator with cartesian products where no duplicates are present in the sense of sets.
import itertools
A = list(range(1,10))
iterator = itertools.product(A,repeat=2)
print(list(iterator))
>> [(1,1),(1,2),...,(2,1),...,(9,9)]
Above is wrong in the sense that set((1,2)) == set((2,1)). I could do
B = list()
for i in iterator:
if all(set(i) != set(j) for j in B):
B.append(i)
and get a list of the wanted output, but I would like to stay away from lists since I run into memory problems when scaling the repeat-option.
Can anyone help me out?
A = list(range(1,10))
k = []
for i, v in enumerate(A):
for _, v1 in enumerate(A[i:]):
k.append((v, v1))
print(k)
Output is
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 6), (6, 7), (6, 8), (6, 9), (7, 7), (7, 8), (7, 9), (8, 8), (8, 9), (9, 9)]
This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 4 years ago.
I have list of lists of tuples:
a = [[(1, 2), (3, 4), (5, 6)], [(7, 8), (9, 10)]]
How can I make one list of tuples:
b = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
Naive way is:
b = []
for c in a:
for t in c:
b.append(t)
List comprehension or any other ideas are welcome.
Using itertools
demo:
import itertools
a = [[(1, 2), (3, 4), (5, 6)], [(7, 8), (9, 10)]]
print(list(itertools.chain(*a)))
Output:
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
This operation is called 'flatten' in some of other languages.
In python, followings method might be shortest.
a = [[(1, 2), (3, 4), (5, 6)], [(7, 8), (9, 10)]]
sum(a, [])
// [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
It also work in the case the parent list have many child lists.
b = [[1],[2],[3],[4],[5]]
sum(b, [])
// [1, 2, 3, 4, 5]
You don't want to append, you want to extend. You can use the really simple loop
a = [[(1, 2), (3, 4), (5, 6)], [(7, 8), (9, 10)]]
single_level_list = []
for lst in a:
single_level_list.extend(lst)
print(single_level_list)
>>> [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
I'm trying generate a bunch of pairs from a list in python --- I figured out a way of doing it using for loops:
keys = range(10)
keypairs = list()
for i in range(len(keys)):
for j in range(i+1, len(keys)):
keypairs = keypairs + [(keys[i], keys[j])]
Is there a more "python style" way of doing this? My method doesn't seem very elegant ...
You want two range loops, one from 0 to n and the inner from each i of the first range + 1 to n using a list comp:
n = 10
pairs = [(i, j) for i in range(n) for j in range(i+1, n)]
from pprint import pprint as pp
pp(pairs,compact=True)
[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 2),
(1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 3), (2, 4), (2, 5),
(2, 6), (2, 7), (2, 8), (2, 9), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9),
(4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 6), (5, 7), (5, 8), (5, 9), (6, 7),
(6, 8), (6, 9), (7, 8), (7, 9), (8, 9)]
Which exactly matches your output.
You want to check list comprehension:
sorted([(i, j) for j in range(10) for i in range(10) if j > i])
I would use itertools for that. Check combinations_with_replacement and combinations methods.
And here is the code sample:
import itertools
list(itertools.combinations(keys, 2))
EDITED: Yes, I noticed that it should be combinations, not combinations_with_replacements.