Generating multiple combinations of strings [duplicate] - python

This question already has answers here:
How to get all possible combinations of a list’s elements?
(32 answers)
Closed 1 year ago.
I have a list of n letters as strings such as:
input: ["A", "B", "C", "D"]
What I need to do is create all possible combinations of these letters with given length, for example if:
L = 2
output: ["A", "B"], ["A", "C"], ["A", "D"], ["B", "C"], ["B", "D"], ["C", "D"]
L = 3
output: ["A", "B", "C"], ["A", "B", "D"], ["A", "C", "D"], ["B", "C", "D"]

You can use itertools.permutations to get permutations of a specified length.
from itertools import permutations
print(list(permutations(my_list, L)))

This is your standard combinations which is available in itertools:
import itertools
characters = "ABCD"
print(list(itertools.combinations(characters, 2)))
print(list(itertools.combinations(characters, 3)))
You'll find other useful functions for iterating inside itertools such as permutations.

You can simply use itertools and permutations. You pass it your list of characters and the length of the permutation.
import itertools
my_list = ["A", "B", "C", "D"]
print(list(itertools.permutations(my_list, 2)))
# [('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C')]
print(list(itertools.permutations(my_list, 3)))
#[('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'B'), ('A', 'C', 'D'), ('A', 'D', 'B'), ('A', 'D', 'C'), ('B', 'A', 'C'), ('B', 'A', 'D'), ('B', 'C', 'A'), ('B', 'C', 'D'), ('B', 'D', 'A'), ('B', 'D', 'C'), ('C', 'A', 'B'), ('C', 'A', 'D'), ('C', 'B', 'A'), ('C', 'B', 'D'), ('C', 'D', 'A'), ('C', 'D', 'B'), ('D', 'A', 'B'), ('D', 'A', 'C'), ('D', 'B', 'A'), ('D', 'B', 'C'), ('D', 'C', 'A'), ('D', 'C', 'B')]

Related

Python Dictionary: Checking if items in a list are present in any of the lists in the dictionary

I have a dictionary containing transactions like so:
transactions = {
"T1": ["A", "B", "C", "E"],
"T2": ["A", "D", "E"],
"T3": ["B", "C", "E"],
"T4": ["B", "C", "D", "E"],
"T5": ["B", "D", "E"]
}
I then have an items list as so:
items = [('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
and what I am trying to figure out, is how I can calculate the number of occurrences these items have in the transactions dictionary. For example in this scenario, I would be returning a dictionary that would look something like:
{('B','C'): 3, ('B', 'D'): 2, ('B', 'E'): 4, ('C', 'D'): 1, ('C', 'E'): 3, ('D', 'E'): 3}
I have the following function:
def get_num_occurrences(items, transactions):
occurr = dict()
for x in items:
occurr[x] = 0
for transaction in transactions.values():
for item in transaction:
occurr[item] += 1
return occurr
This works for 1 item-itemsets (if the list of items was instead items = ["A", "B", "C", "D", "E"]). But I cannot figure out how to implement this same method for 2 item-itemsets (items = [('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]) or if I then had 3 item-itemsets (items = [('B', 'C', 'D'), ('C', 'D', 'E'), ('A', 'C', 'E')]) etc...
Use sets to determine if your item is a subset of the transaction.
transactions = {
"T1": ["A", "B", "C", "E"],
"T2": ["A", "D", "E"],
"T3": ["B", "C", "E"],
"T4": ["B", "C", "D", "E"],
"T5": ["B", "D", "E"]
}
items = [('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
result = {}
for item in items:
count = 0
for transaction in transactions.values():
if set(item).issubset(set(transaction)):
count += 1
result[item] = count
print(result)
The result is {('B', 'C'): 3, ('B', 'D'): 2, ('B', 'E'): 4, ('C', 'D'): 1, ('C', 'E'): 3, ('D', 'E'): 3}.
With a dictionary comprehension you can write all of this in one line.
result = {item: sum(set(item).issubset(set(t)) for t in transactions.values()) for item in items}
This way it really doesn't matter how many elements are in your item an you can use an efficient dictionary lookup.
def count_items(item):
if item in dictionary:
dictionary[item] += 1
else:
dictionary.update({item: 1})
for item in items: count_items(item)

How to find all unique combinations out of two list in python?

I have two lists:
l1 = ['a', 'b', 'c']
l2 = ['e', 'f', 'g']
And I want to generate all possible combinations of their pairings
Desired Output:
What is the best way to do it?
Right now I have written this code which works but seems highly inefficient.
You only need to permute the second list:
from itertools import permutations
l1 = ['a', 'b', 'c']
l2 = ['e', 'f', 'g']
pairs = [tuple(zip(l1, p)) for p in permutations(l2)]
print(pairs)
Output:
[(('a', 'e'), ('b', 'f'), ('c', 'g')),
(('a', 'e'), ('b', 'g'), ('c', 'f')),
(('a', 'f'), ('b', 'e'), ('c', 'g')),
(('a', 'f'), ('b', 'g'), ('c', 'e')),
(('a', 'g'), ('b', 'e'), ('c', 'f')),
(('a', 'g'), ('b', 'f'), ('c', 'e'))]
The easiest way to think about this is that each set of output values is the result of pairing the elements of the first list with some permutation of the elements of the second list. So you just need to generate all possible permutations if n elements, then use that as a permutation of the elements of the second list, pairing them with the elements of the first list.
The most flexible way to implement it is by defining a simple generator function:
from itertools import permutations
def gen_perm_pairs(l1, l2):
cnt = len(l1)
assert len(l2) == cnt
for perm in permutations(range(cnt)):
yield tuple((l1[i], l2[perm[i]]) for i in range(cnt))
You can then call it to generate the desired results:
l1 = ['a', 'b', 'c']
l2 = ['e', 'f', 'g']
for pairs in gen_perm_pairs(l1, l2):
print(pairs)
This produces the following:
(('a', 'e'), ('b', 'f'), ('c', 'g'))
(('a', 'e'), ('b', 'g'), ('c', 'f'))
(('a', 'f'), ('b', 'e'), ('c', 'g'))
(('a', 'f'), ('b', 'g'), ('c', 'e'))
(('a', 'g'), ('b', 'e'), ('c', 'f'))
(('a', 'g'), ('b', 'f'), ('c', 'e'))

Get all combinations of a list in Python [duplicate]

This question already has answers here:
How to calculate a Cartesian product of a list with itself [duplicate]
(2 answers)
Closed 2 years ago.
I would like to get all combinations of a list:
L = ["a","b","c"]
combinations(L,length=2)
# [("a","a"),("a","b"),("a","c"),("b","a"),("b","b"),("b","c"),("c","a"),("c","b"),("c","c")]
I've tried
itertools.combinations()
but this returned
[('a', 'b'), ('a', 'c'), ('b', 'c')]
When I use itertools.permutations(), it just returns the combinations with the length of the iteration, which is also not what I want.
Any librarys / function that I can use, without writing my own?
You can use itertools.product with repeat=2 like so:
from itertools import product
L = ["a","b","c"]
print(list(product(L, repeat=2)))
#[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]
A simple list comprehesion can do the job too.
L = ["a","b","c"]
print([(a,b) for a in L for b in L])
#[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]
The product function from itertools offers a solution.
In [17]: from itertools import product
In [18]: L = ["a","b","c"]
In [19]: list(product(L, L))
Out[19]:
[('a', 'a'),
('a', 'b'),
('a', 'c'),
('b', 'a'),
('b', 'b'),
('b', 'c'),
('c', 'a'),
('c', 'b'),
('c', 'c')]
itertools module has a function called product which is what you are looking for.
>>> L = ["a", "b", "c"]
>>> list(itertools.product(L, repeat=2))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]
You can use the second parameter of itertools.permutations():
from itertools import permutations
L = ["a","b","c"]
print([n for n in permutations(L,2)]+[(i,i) for i in L])
Output:
[('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('a', 'a'), ('b', 'b'), ('c', 'c')]
From the documentation:
itertools.permutations(iterable, r=None)
Return successive r length permutations of elements in the iterable.
If r is not specified or is None, then r defaults to the length of the iterable and all possible full-length permutations are generated.

How to unpack the data in the sublists into one list? [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 3 years ago.
Consider following code:
string = "ABCD"
variations = [list(itertools.combinations(string,x)) for x in range(1,5)]
variations
It produces following output:
[[('A',), ('B',), ('C',), ('D',)],
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')],
[('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')],
[('A', 'B', 'C', 'D')]]
But the output I would like is:
[('A',),
('B',),
('C',),
('D',),
('A', 'B'),
('A', 'C'),
('A', 'D'),
('B', 'C'),
('B', 'D'),
('C', 'D'),
('A', 'B', 'C'),
('A', 'B', 'D'),
('A', 'C', 'D'),
('B', 'C', 'D'),
('A', 'B', 'C', 'D')]
In other words, I want to unpack all the data in the sublists into one list (in the shortest way possible)
I've tried to use asterisk:
string = "ABCD"
variations = [*list(itertools.combinations(string,x)) for x in range(1,5)]
But it throws following error:
SyntaxError: iterable unpacking cannot be used in comprehension
What should I do? (Again, I would like to keep things concise)
Just add another for to your list comprehension that loops over the combinations:
variations = [y for x in range(1, 5) for y in itertools.combinations(string, x)]
print(variations)
Output:
[('A',), ('B',), ('C',), ('D',), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D'), ('A', 'B', 'C', 'D')]
You can perform a nested iteration inside the list comprehension. Something like this:
[y for x in range(1,5) for y in itertools.combinations(string, x)]
variations = [e for x in range(1,5) for e in (itertools.combinations(string,x)) ]

Python - Removing tuples by prefix and suffix from list

What's the fastest way to remove tuples from a python list (and update the list with the removed tuples) according to what the tuple starts with or ends with.
Example:
import itertools
l1 = ["a", "b", "c"]
l2 = ["d", "e", "f"]
tupl_lst = list(itertools.product(l1, l2))
tupl_lst
Out[42]:
[('a', 'd'),
('a', 'e'),
('a', 'f'),
('b', 'd'),
('b', 'e'),
('b', 'f'),
('c', 'd'),
('c', 'e'),
('c', 'f')]
I want to remove all tuples that starts with 'a' OR ends with 'f' so that my output will look as follows:
[('b', 'd'),
('b', 'e'),
('c', 'd'),
('c', 'e')]
What is the fastest way to do it ?
You can even skip the itertools.product()and just use one list-comprehension:
l1 = ["a", "b", "c"]
l2 = ["d", "e", "f"]
tupl_lst = [(x, y) for x in l1 for y in l2 if x!="a" and y!="f"]
#output
[('b', 'd'), ('b', 'e'), ('c', 'd'), ('c', 'e')]
with a list comprehension:
[t for t in tupl_lst if t[0]!='a' and t[1]!='f']
with filter:
list(filter(lambda t: t[0]!='a' and t[1]!='f',tupl_lst))
Avoid the prefix (a) and suffix (f) altogether by iterating over slices of the lists.
[(x, y) for x in l1[1:] for y in l2[:-1]]
# [('b', 'd'), ('b', 'e'), ('c', 'd'), ('c', 'e')]

Categories