Related
I have two lists. One list contains X coordinate values and second list contains Y coordinate values. Using these two lists, I want to make a tupple which is sorted by their first element.
X coordinate = [2, 3, 4, 4, 3, 2, 1, 0, 0, 1, 1, 1, 1, 2, 2, 2]
Y coordinate = [3, 3, 3, 4, 4, 4, 4, 4, 3, 3, 2, 1, 0, 0, 1, 2]
I want my output like this:
[(0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 3), (4, 4)]
To achieve this result, I wrote below code and got an output mentioend below.
merged_list = list(tuple(zip(X3_coordinate, Y3_coordinate)))
merged_list.sort(key=lambda x: x[0])
merged_list
Output:
[(0, 4), (0, 3), (1, 4), (1, 3), (1, 2), (1, 1), (1, 0), (2, 3), (2, 4), (2, 0), (2, 1), (2, 2), (3, 3), (3, 4), (4, 3), (4, 4)]
Kindly let me know what I am doing wrong and give some suggestions of code.
instead of list(tuple()) just do list()
sort with no key, it'll do element-wise by default
use sorted do both generate the list and sort
X_coordinate = [2, 3, 4, 4, 3, 2, 1, 0, 0, 1, 1, 1, 1, 2, 2, 2]
Y_coordinate = [3, 3, 3, 4, 4, 4, 4, 4, 3, 3, 2, 1, 0, 0, 1, 2]
merged_list = sorted(zip(X_coordinate, Y_coordinate))
print(merged_list)
You've sorted by x, but not later by y:
merged_list.sort(key=lambda x: (x[0], x[1]))
[(0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 3), (4, 4)]
By using "key=lambda x: x[0]", you are forcing it to be sorted only by the first element, what you seek is a sort where-in you give priority to the first element, but if the values are same you wish to sort it by the subsequent elements.
X3_coordinate = [2, 3, 4, 4, 3, 2, 1, 0, 0, 1, 1, 1, 1, 2, 2, 2]
Y3_coordinate = [3, 3, 3, 4, 4, 4, 4, 4, 3, 3, 2, 1, 0, 0, 1, 2]
merged_list = list(zip(X3_coordinate, Y3_coordinate))
merged_list.sort()
print(merged_list)
Output:
[(0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 3), (4, 4)]
P = [(2, 2, 3), (2, 3, 2), (3, 2, 2)]
X = [[(1, 2, 4), (1, 4, 2), (2, 1, 4), (2, 4, 1), (4, 1, 2), (4, 2, 1)], [(1, 2, 6), (1, 6, 2), (2, 1, 6), (2, 6, 1), (6, 1, 2), (6, 2, 1)], [(1, 3, 6), (1, 6, 3), (3, 1, 6), (3, 6, 1), (6, 1, 3), (6, 3, 1)]]
How can I print all the permutations of the above 2 lists in the form:
P1(X1) P2(x2) P3(x3)
for example:
2(1) 2(2) 3(4),
2(1) 2(4) 3(2),
2(2) 2(1) 3(4) and so on
i.e. first tuple from P combines with all tuples of X then second tuple of P combines with all tuples of X and so on.
you could use itertools.product and zip this way:
from itertools import product
P = [(2, 2, 3), (2, 3, 2), (3, 2, 2)]
X = [[(1, 2, 4), (1, 4, 2), (2, 1, 4), (2, 4, 1), (4, 1, 2), (4, 2, 1)],
[(1, 2, 6), (1, 6, 2), (2, 1, 6), (2, 6, 1), (6, 1, 2), (6, 2, 1)],
[(1, 3, 6), (1, 6, 3), (3, 1, 6), (3, 6, 1), (6, 1, 3), (6, 3, 1)]]
for p, xs in product(P, X):
for x in xs:
print(" ".join(f"{a}({b})" for a, b in zip(p, x)))
this outputs
2(1) 2(2) 3(4)
2(1) 2(4) 3(2)
2(2) 2(1) 3(4)
2(2) 2(4) 3(1)
2(4) 2(1) 3(2)
2(4) 2(2) 3(1)
2(1) 2(2) 3(6)
2(1) 2(6) 3(2)
2(2) 2(1) 3(6)
...
Using plain Python or any Python libraries, how would you go about finding all possible combinations of elements in a list l that equal a given value val using addition, subtraction, or multiplication? Assume the length of the list isn't always the same, assume each element in the list can only be used once in each combination, and assume there isn't any use of parentheses.
For example:
We're given a list of numbers: l = [1,2,3,4]
We're given a value equaling the combination of values: val = 6
The output would include the following:
[2,4], since 2+4=6
And [4,2], since 4+2=6
And [1,3,2], since 1+3+2=6
And [1,2,4], since 1*2+4=6
etc.
I've tried using itertools.permutations:
>>> from itertools import permutations
>>> l = [1,2,3,4]
>>> val = 6
>>> correct_combos = []
>>> for i in range(1, len(l)+1):
... for p in permutations(l, r=i):
... if sum(p) == val:
... correct_combos.append(p)
I'm able to only implement the code for testing the sum of all combinations of elements in the list.
>>> print(correct_combos)
[(2, 4), (4, 2)]
I'm stuck on finding permutations of elements in the list using a combination of addition, subtraction, and multiplication.
I don't know if this algorithm is efficient, but it works fine:
from itertools import permutations, product
l = [1,2,3,4]
val = 6
operator = ['+', '-', '*']
correct_combos=[]
for r in range(1, len(l)+1):
for item in permutations(l,r):
for unit in product(operator, repeat=r-1):
res=""
for idx in range(0,r-1):
res+=str(item[idx])+unit[idx]
res+=str(item[-1])
if(val==eval(res)):
if item not in correct_combos:
correct_combos.append(item)
print(correct_combos)
Output
[(2, 3), (2, 4), (3, 2), (4, 2), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 4, 2), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 4, 1), (3, 1, 2), (3, 1, 4), (3, 2, 1), (3, 4, 1), (4, 1, 2), (4, 1, 3), (4, 2, 1), (4, 3, 1), (1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
Non recursive solution:
from itertools import permutations, product, accumulate
from collections import deque
from operator import add, sub, mul
l = [1, 2, 3, 4]
val = 6
correct_combos = []
def is_correct(p, val, ops=[add, sub, mul]):
if len(p) == 1:
return p[0] == val
for op in product(ops, repeat=len(p) - 1):
iop = iter(op)
l = deque(accumulate(p, lambda a, b: next(iop)(a, b)), maxlen=1)[0]
if l == val:
return True
return False
for i in range(1, len(l) + 1):
for p in permutations(l, r=i):
if is_correct(p, val):
correct_combos.append(p)
print(correct_combos)
Prints:
[(2, 3), (2, 4), (3, 2), (4, 2), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 4, 2), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 4, 1), (3, 1, 2), (3, 1, 4), (3, 2, 1), (3, 4, 1), (4, 1, 2), (4, 1, 3), (4, 2, 1), (4, 2, 3), (4, 3, 1), (1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
You can use a recursive generator function:
from operator import add, sub, mul
l = [1,2,3,4]
val = 6
def combos(c = [], r_exp = None):
if r_exp == val:
yield c
else:
for i in filter(lambda x:x not in c, l):
if not c:
yield from combos(c=[i], r_exp = i)
else:
for s, f in [['+', add], ['-', sub], ['*', mul]]:
yield from combos(c=c+[s, i], r_exp = f(r_exp, i))
print([''.join(map(str, i)) for i in combos()])
Output:
['1+2+3', '1-2+3+4', '1-2+4+3', '1*2*3', '1*2+4', '1+3+2', '1+3-2+4', '1+3+4-2', '1*3*2', '1+4-2+3', '1+4+3-2', '1*4+2', '1*4-2*3', '2+1+3', '2*1*3', '2*1+4', '2+3+1', '2*3', '2+4', '2*4+1-3', '2*4-3+1', '3+1+2', '3+1-2+4', '3+1+4-2', '3-1+4', '3-1*4-2', '3*1*2', '3+2+1', '3-2+1+4', '3-2+4+1', '3*2', '3+4+1-2', '3+4-1', '3+4-2+1', '4+1-2+3', '4+1+3-2', '4-1*2', '4-1+3', '4*1+2', '4*1-2*3', '4+2', '4-2+1+3', '4-2*1*3', '4-2+3+1', '4-2*3', '4*2+1-3', '4*2-3+1', '4+3+1-2', '4+3-1', '4+3-2+1']
To just get the tuple results, only a small change needs to be made:
for f in [add, sub, mull]:
yield from combos(c=c+[i], r_exp = f(r_exp, i))
...
print(list(map(tuple, combos())))
Output:
[(1, 2, 3), (1, 2, 3, 4), (1, 2, 4, 3), (1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 2, 4), (1, 3, 4, 2), (1, 3, 2), (1, 4, 2, 3), (1, 4, 3, 2), (1, 4, 2), (1, 4, 2, 3), (2, 1, 3), (2, 1, 3), (2, 1, 4), (2, 3, 1), (2, 3), (2, 4), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2), (3, 1, 2, 4), (3, 1, 4, 2), (3, 1, 4), (3, 1, 4, 2), (3, 1, 2), (3, 2, 1), (3, 2, 1, 4), (3, 2, 4, 1), (3, 2), (3, 4, 1, 2), (3, 4, 1), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 1, 2), (4, 1, 3), (4, 1, 2), (4, 1, 2, 3), (4, 2), (4, 2, 1, 3), (4, 2, 1, 3), (4, 2, 3, 1), (4, 2, 3), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 1), (4, 3, 2, 1)]
from itertools import chain, combinations
def subSet(l):
return chain.from_iterable(combinations(l, r) for r in range(len(l) + 1))
def whatWeWant(l, val):
x = 0
for i in l:
x += i
if x == val:
return True
return False
l = [1, 2, 3, 4]
val = 6
allSubSets = list(subSet(l))
ans = []
for subSet in allSubSets:
if whatWeWant(subSet, val):
ans.append(subSet)
With this code you can find what you want but you have to specifically say the possible combinations(in whatWeWant method).
I want to know how to randomly pick k items from a list of n size for ALL possible combinations.
For example, let A = [1, 2, 3, 4] and K = 3. Then it should return [1, 2, 3], [1, 2, 4], [1, 3, 4], and [2, 3, 4].
You are looking for itertools.combinations. For example:
>>> my_list = A = [1, 2, 3, 4]
>>> k = 3
>>> from itertools import combinations
>>> list(combinations(my_list, k))
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
If the ordering inside the results matters you might use itertools.permutations to get all permutations as well - putting them into a set removes duplicates stemming from duplicate numbers in your list
import itertools
n = 3
my_list = [1, 2, 3, 2 ,1]
print( set(itertools.permutations(my_list, n))) # or list, see below
Output:
{(1, 2, 1), (3, 1, 2), (2, 3, 2), (1, 3, 2), (3, 1, 1), (3, 2, 1), (1, 2, 2),
(1, 1, 3), (2, 2, 1), (2, 1, 1), (1, 3, 1), (2, 3, 1), (1, 2, 3), (1, 1, 2), ...}
# with set: 17 items
[(1, 2, 3), (1, 2, 2), (1, 2, 1), (1, 3, 2), (1, 3, 2), (1, 3, 1), (1, 2, 2),
(1, 2, 3), (1, 2, 1), (1, 1, 2), (1, 1, 3), (1, 1, 2), (2, 1, 3), (2, 1, 2), ...]
# with list: 60 items
Difference between permutations and combinations:
# permutations - based on all values on any position in the resulttuple
[(1, 2, 3), (1, 2, 2), (1, 2, 1), (1, 3, 2), (1, 3, 2), (1, 3, 1), (1, 2, 2), (1
, 2, 3), (1, 2, 1), (1, 1, 2), (1, 1, 3), (1, 1, 2), (2, 1, 3), (2, 1, 2), (2, 1
, 1), (2, 3, 1), (2, 3, 2), (2, 3, 1), (2, 2, 1), (2, 2, 3), (2, 2, 1), (2, 1, 1
), (2, 1, 3), (2, 1, 2), (3, 1, 2), (3, 1, 2), (3, 1, 1), (3, 2, 1), (3, 2, 2),
(3, 2, 1), (3, 2, 1), (3, 2, 2), (3, 2, 1), (3, 1, 1), (3, 1, 2), (3, 1, 2), (2,
1, 2), (2, 1, 3), (2, 1, 1), (2, 2, 1), (2, 2, 3), (2, 2, 1), (2, 3, 1), (2, 3,
2), (2, 3, 1), (2, 1, 1), (2, 1, 2), (2, 1, 3), (1, 1, 2), (1, 1, 3), (1, 1, 2)
, (1, 2, 1), (1, 2, 3), (1, 2, 2), (1, 3, 1), (1, 3, 2), (1, 3, 2), (1, 2, 1), (
1, 2, 2), (1, 2, 3)]
# combinations - based on position in source list not on value order in tuple preserved
[(1, 2, 3), (1, 2, 2), (1, 2, 1), (1, 3, 2), (1, 3, 1), (1, 2, 1), (2, 3, 2), (2
, 3, 1), (2, 2, 1), (3, 2, 1)]
Press any key to continue . . .
Imagine I have a list of tuples in this format:
(1, 2, 3)
(1, 0, 2)
(3, 9 , 11)
(0, 2, 8)
(2, 3, 4)
(2, 4, 5)
(2, 7, 8)
....
How could I sort the list by the first element of the tuples, and then by the second? I'd like to get to this list:
(0, 2, 8)
(1, 0, 2)
(1, 2, 3)
(2, 3, 4)
(2, 4, 5)
(2, 7, 8)
(3, 9 , 11)
I was thinking to do a sort for the first element, and then go through the list, and build a hash with subarrays. I will probably overcomplicate things :), and this is why I asked for other ways of doing this sort.
Why not simply let python sort the list for you ?
my_list = [
(1, 2, 3),
(1, 0, 2),
(3, 9 , 11),
(0, 2, 8),
(2, 3, 4),
(2, 4, 5),
(2, 7, 8),
]
print sorted(my_list)
>>>[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]
Python automagically does the right thing:
>>> a = [(1, 2, 3), (1, 0, 2), (3, 9, 11), (0, 2, 8), (2, 3, 4), (2, 4, 5), (2, 7, 8)]
>>> a.sort()
>>> a
[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]
Tuples are already sorted that way.
Try this:
#!/usr/bin/python2
l = [
(1, 2, 3),
(1, 0, 2),
(3, 9 , 11),
(0, 2, 8),
(2, 3, 4),
(2, 4, 5),
(2, 7, 8),
]
l.sort()
print l
If you don't mind sorting by all three elements, this is really trivial:
>>> l = [(1, 2, 3), (1, 0, 2), (3, 9, 11), (0, 2, 8), (2, 3, 4), (2, 4, 5), (2, 7, 8)]
>>> l.sort()
>>> l
[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]
>>> x = [
... (1, 2, 3),
... (1, 0, 2),
... (3, 9 , 11),
... (0, 2, 8),
... (2, 3, 4),
... (2, 4, 5),
... (2, 7, 8),
... ]
>>> x.sort()
>>> x
[(0, 2, 8), (1, 0, 2), (1, 2, 3), (2, 3, 4), (2, 4, 5), (2, 7, 8), (3, 9, 11)]