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.
Related
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)]
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 want to combine N lists and keep only the values that are in every single one of them. I don't know how many lists there are, so the code must be dynamic.
a_list = [(3, -1), (3, -1), (3, 0), (4, -1), (3, 1), (5, -1), (3, 2), (6, -1), (3, 3), (7, -1), (7, -1), (3, 3), (7, 0), (4, 3), (7, 1), (5, 3), (7, 2), (6, 3), (7, 3), (7, 3)]
b_list = [(-3, 3), (-3, 3), (-3, 4), (-2, 3), (-3, 5), (-1, 3), (-3, 6), (0, 3), (-3, 7), (1, 3), (-3, 8), (2, 3), (-3, 9), (3, 3), (3, 3), (-3, 9), (3, 4), (-2, 9), (3, 5), (-1, 9), (3, 6), (0, 9), (3, 7), (1, 9), (3, 8), (2, 9), (3, 9), (3, 9)]
a = set(a_list)
b = set(b_list)
print(list(a&b))
This code works perfectly for a known number of lists, but I don't know how many lists there are.
Note: "Unknown number of lists" means it depends on the values the script is ran with.
Edit: N > 0
You can use the built-in set function intersection:
print (set.intersection(*map(set, lists)))
Use reduce
import functools
list_of_sets = [set(x) for x in list_of_lists]
intersection = functools.reduce(lambda x, y: x & y, list_of_sets)
This is my first question here =):
My problem is what is stated in the title. I want to simply sort a list of tuples with 2 elements. It should work with sorted but it still returns the unsorted List,... it seems to do nothing.
Input:
#"L =[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]" Its an example.
for line in stdin:
L = [int(i) for i in line.split()]
n = L[0]
V = [i for i in range(n)]
edgelist = L[1:]
EDGE = [(edgelist[i],edgelist[i+1]) for i in range(0,len(edgelist)-1,2) ]
mK = missingKnots(edgelist)
EDGE = sorted(EDGE)
EDGE = list(set(EDGE))
Output:
[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]
Should be:
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Unsorted =(.
Thanks for reading!
Sort and return new list:
>>> L =[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]
>>> sorted(L)
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Sort in place:
>>> L.sort()
>>> L
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
Don't do the set() afterward. Sets are unordered.
>>> list(set(L))
[(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)] # now it's messed up again.
Ideally, to sort and remove duplicates:
>>> L = [(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5), (0, 1)]
>>> sorted(set(L))
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]
With lambda expression, you can customise the rules of sorting.
EDGE = [(0, 1), (4, 6), (5, 7), (0, 6), (0, 4), (2, 5)]
EDGE = sorted(EDGE, key=lambda x: (x[0],x[1]) )
print EDGE
result:
[(0, 1), (0, 4), (0, 6), (2, 5), (4, 6), (5, 7)]