This question already has answers here:
How to get the cartesian product of multiple lists
(17 answers)
Closed 3 years ago.
If I have the list my_list = [['a', 'b'], ['c', 'd', 'e'], how can I create a list of all possible tuples where each tuple contains a single element from each sublist? For example:
('a', 'e') is valid
('a', 'b') is invalid
('b', 'c') is valid
('c', 'd') is invalid
Importantly, my_list can contain any number of elements (sublists) and each sublist can be of any length. I tried to get a recursive generator off the ground, but it's not quite there.
I’d like to try and use recursion rather than itertools.
The logic was to iterate through 2 sublists at a time, and store those results as input to the next sublist's expansion.
def foil(lis=l):
if len(lis) == 2:
for x in l[0]:
for y in l[1]:
yield x + y
else:
for p in foil(l[:-1]):
yield p
for i in foil():
print(i)
However, this obviously only works for the len(my_list) == 2. It also needs to work with, say, my_list = [['a'], ['b'], ['c', 'd']] which would return:
('a', 'b', 'c')
('a', 'b', 'd')
Cheers!
Use itertools.product:
import itertools
my_list = [['a', 'b'], ['c', 'd', 'e']]
print(list(itertools.product(*my_list)))
# [('a', 'c'), ('a', 'd'), ('a', 'e'), ('b', 'c'), ('b', 'd'), ('b', 'e')]
my_list = [['a'], ['b'], ['c', 'd']]
print(list(itertools.product(*my_list)))
#[('a', 'b', 'c'), ('a', 'b', 'd')]
Related
I have this array:
lst = ['A', 'B', 'C']
How could I append a string 'D' to each element and convert every set as a tuple:
lst2= [('A', 'D'),
('B', 'D'),
('C', 'D')]
Like this, using a list comprehension:
lst = ['A', 'B', 'C']
lst2 = [(x, 'D') for x in lst]
lst2
=> [('A', 'D'), ('B', 'D'), ('C', 'D')]
By the way, it's a bad idea to call a variable list, that clashes with a built-in function. I renamed it.
alternative solution is use zip_longest
from itertools import zip_longest
list(zip_longest(['A', 'B', 'C'], [], fillvalue='D'))
the result wiil be:
[('A', 'D'), ('B', 'D'), ('C', 'D')]
list2 = [(i, 'D') for i in list]
(apart from the fact that list is a very bad variable name)
Another option using zip:
x = ['A', 'B', 'C']
res = list(zip(x,'D'*len(x)))
list1 = ['A', 'B', 'C']
list2 = []
for i in list1:
list2.append((i, 'D'))
print(list2)
You can use the function product():
from itertools import product
lst = ['A', 'B', 'C']
list(product(lst, 'D'))
# [('A', 'D'), ('B', 'D'), ('C', 'D')]
I have arrays such as these, and each pattern designates a combination shape with each number representing the size of the combination.
pattern 0: [1, 1, 1, 1]
pattern 1: [2, 1, 1]
pattern 2: [3, 1]
pattern 3: [4]
...
I also have a char-valued list like below. len(chars) equals the sum of the upper array's value.
chars = ['A', 'B', 'C', 'D']
I want to find all combinations of chars following a given pattern. For example, for pattern 1, 4C2 * 2C1 * 1C1 is the number of combinations.
[['A', 'B'], ['C'], ['D']]
[['A', 'B'], ['D'], ['C']]
[['A', 'C'], ['B'], ['D']]
[['A', 'C'], ['D'], ['B']]
[['A', 'D'], ['B'], ['C']]
[['A', 'D'], ['C'], ['B']]
...
But I don't know how to create such combination arrays. Of course I know there are a lot of useful functions for combinations in python. But I don't know how to use them to create a combination array of combinations.
EDITED
I'm so sorry my explanation is confusing. I show a simple example.
pattern 0: [1, 1]
pattern 1: [2]
chars = ['A', 'B']
Then, the result should be like below. So first dimension should be permutation, but second dimension should be combination.
pat0: [['A'], ['B']]
pat0: [['B'], ['A']]
pat1: [['A', 'B']] # NOTE: [['B', 'A']] is same in my problem
You can use recursive function that takes the first number in pattern and generates all the combinations of that length from remaining items. Then recurse with remaining pattern & items and generated prefix. Once you have consumed all the numbers in pattern just yield the prefix all the way to caller:
from itertools import combinations
pattern = [2, 1, 1]
chars = ['A', 'B', 'C', 'D']
def patterns(shape, items, prefix=None):
if not shape:
yield prefix
return
prefix = prefix or []
for comb in combinations(items, shape[0]):
child_items = items[:]
for char in comb:
child_items.remove(char)
yield from patterns(shape[1:], child_items, prefix + [comb])
for pat in patterns(pattern, chars):
print(pat)
Output:
[('A', 'B'), ('C',), ('D',)]
[('A', 'B'), ('D',), ('C',)]
[('A', 'C'), ('B',), ('D',)]
[('A', 'C'), ('D',), ('B',)]
[('A', 'D'), ('B',), ('C',)]
[('A', 'D'), ('C',), ('B',)]
[('B', 'C'), ('A',), ('D',)]
[('B', 'C'), ('D',), ('A',)]
[('B', 'D'), ('A',), ('C',)]
[('B', 'D'), ('C',), ('A',)]
[('C', 'D'), ('A',), ('B',)]
[('C', 'D'), ('B',), ('A',)]
Note that above works only with Python 3 since it's using yield from.
I have a list like this:
list_input = [(a,b), (a,c), (a,d), (z,b), (z,e)]
I want to extract b, c and d when start it with "a" not with "z" and put in a list
I could not figure out how to do it, any advice?
Filter your list items on the first value, collecting the second:
[second for first, second in list_input if first == 'a']
Demo:
>>> list_input = [('a', 'b'), ('a', 'c'), ('a', 'd'), ('z', 'b'), ('z', 'e')]
>>> [second for first, second in list_input if first == 'a']
['b', 'c', 'd']
You could also do it explicitly:
In [8]: [list_input[i][1] for i in xrange(len(list_input)) if list_input[i][0] =='a']
Out[8]: ['b', 'c', 'd']
Or;
list_input = [("a","b"), ("a","c"), ("a","d"), ("z","b"), ("z","e")]
print ([x[1] for x in list_input if x[0]=="a"])
>>>
['b', 'c', 'd']
>>>
Manipulate it with indices. You can display that specific pairs too;
print ([(x,x[1]) for x in list_input if x[0]=="a"])
output;
>>>
[(('a', 'b'), 'b'), (('a', 'c'), 'c'), (('a', 'd'), 'd')]
>>>
How to turn multiple lists into one list of sublists, where each sublist is made up of the items at the same index across the original lists?
lsta = ['a','b','c','d']
lstb = ['a','b','c','d']
lstc = ['a','b','c','d']
Desired_List = [['a','a','a'],['b','b','b'],['c','c','c'],['d','d','d']]
I can't seem to use zip here, so how would I do this?
List of list will give like this:
>>> [list(x) for x in zip(lsta, lstb, lstc)]
[['a', 'a', 'a'], ['b', 'b', 'b'], ['c', 'c', 'c'], ['d', 'd', 'd']]
>>>
Using zip, under duress:
>>> zip(lsta, lstb, lstc)
[('a', 'a', 'a'), ('b', 'b', 'b'), ('c', 'c', 'c'), ('d', 'd', 'd')]
If Python 3, you'll need to convert the zip to a list:
>>> list(zip(lsta, lstb, lstc))
[('a', 'a', 'a'), ('b', 'b', 'b'), ('c', 'c', 'c'), ('d', 'd', 'd')]
This question already has answers here:
How do I generate all permutations of a list?
(40 answers)
Closed 9 years ago.
Hey I have a list where I would want to get all the different permutations of it i.e
[A,B,C].
I want all different combinations of it. like so [A,C,B], [B,A,C], [B,A,C], [C,A,B] and [C,B,A] i tried using itertools.combinations and I get all combinations just not the ones with all letters in use.
matriks = ["A","B","C"]
combs=[]
for i in xrange(1, len(matriks)+1):
els = [list(x) for x in itertools.combinations(matriks, i)]
combs.append(els)
print(combs)
this gives the following output
[[['A'], ['B'], ['C']], [['A', 'B'], ['A', 'C'], ['B', 'C']], [['A', 'B', 'C']]]
You can simply use itertools.permutations:
>>> from itertools import permutations
>>>
>>> l = ["A","B","C"]
>>>
>>> list(permutations(l))
[('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]