Python Itertools Add List for Every Combination - python

I need to create every combination for list1, but add list2 to every combination of list1.
For example, this creates a combination for every value for list1:
list1 = ["a", "b" , "c"]
list2 = ["d", "e"]
list(itertools.combinations(list1, 2))
[('a', 'b'), ('a', 'c'), ('b', 'c')]
But I would like the result to be:
[('a', 'b', 'd', 'e'), ('a', 'c'', d', 'e'), ('b', 'c', 'd', 'e')]
I have tried these common approaches, but am getting undesired results:
list1 = ["a", "b" , "c"]
list2 = ["d", "e"]
print(list(itertools.combinations(list1, 2)).extend(list2))
None
print(list(itertools.combinations(list1, 2)) + list2)
[('a', 'b'), ('a', 'c'), ('b', 'c'), 'd', 'e']
print(list(itertools.combinations(list1, 2) + list2))
TypeError: unsupported operand type(s) for +: 'itertools.combinations' and 'list'
Any help would be appreciated. Thanks.

You can first generate a tuple of size 2 combinations for each list separately, then compute the cartesian product of those to combination lists:
import itertools
list1 = ["a", "b" , "c"]
list2 = ["d", "e"]
iter1 = itertools.combinations(list1, 2)
iter2 = itertools.combinations(list2, 2)
# If you want to add a subset of size 2 from list 2:
product = itertools.product(iter1, iter2)
answer = list(map(lambda x: (*x[0], *x[1]), product))
# [('a', 'b', 'd', 'e'), ('a', 'c', 'd', 'e'), ('b', 'c', 'd', 'e')]
However, if you want to add all elements of list2 you can use:
import itertools
list1 = ["a", "b" , "c"]
list2 = ["d", "e", "f"]
iter1 = itertools.combinations(list1, 2)
# If you want to add all elements of list2
product = itertools.product(iter1, [list2])
answer = list(map(lambda x: (*x[0], *x[1]), product))
# [('a', 'b', 'd', 'e', 'f'), ('a', 'c', 'd', 'e', 'f'), ('b', 'c', 'd', 'e', 'f')]

Related

Shuffle a list items among dissimilar items

How to shuffle list items keeping the similar items unshuffled? E.g. for the list 'L', I want to shuffle among the unique items.
L=[a,a,b,b,c,c,d,d]
For the above list, I want to get
shuffled_L=[c,c,a,a,d,d,b,b]
Group into tuples, shuffle the tuples, flatten the list again:
>>> from itertools import groupby, chain
>>> from random import shuffle
>>> L = ["a", "a", "b", "b", "c", "c", "d", "d"]
>>> L_ = [tuple(v) for _, v in groupby(L)]
[('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd')]
>>> random.shuffle(L_)
[('b', 'b'), ('a', 'a'), ('d', 'd'), ('c', 'c')]
>>> list(chain.from_iterable(L_))
['b', 'b', 'a', 'a', 'd', 'd', 'c', 'c']
This assumes the original L is already sorted. If it isn't, sort it before the groupby step.
applying #suddents_appearence method from the comments
>>> import random
>>> import itertools
>>> from collections import Counter
>>> L=["a","a","b","b","c","c","d","d"]
>>> count=Counter(L)
>>> sample=random.sample(sorted(count),len(count))
>>> _shuffled_L=list(map(lambda x:[x]*count.get(x),sample))
>>> shuffled_L=list(itertools.chain.from_iterable(_shuffled_L))
>>> shuffled_L
['d', 'd', 'b', 'b', 'a', 'a', 'c', 'c']

Python: 3rd level nested list comprehension not acting as expected

I am trying to get all possible permutations of length 1, 2 and 3 for the charactes "a", "b" and "c"
from itertools import permutations
a = ['a','b', 'c']
perm1 = permutations(a, 1)
perm2 = permutations(a, 2)
perm3 = permutations(a, 3)
p_list = []
p_list.extend(list(perm1))
p_list.extend(list(perm2))
p_list.extend(list(perm3))
str = [[j for j in i] for i in p_list]
print(str[3])
At this point things are expected
When I modify the str = line to this str = [[[''.join(k) for k in j] for j in i] for i in p_list] I would expect to get a list of strings where each permutation is a string with no commas. e.g. ["abc", "a", "b", "c"] etc. but instead I get a list of lists.
First thing: please don't set str as variable.
Below I copied your code, commenting what p_list looks like.
from itertools import permutations
a = ['a','b', 'c']
perm1 = permutations(a, 1)
perm2 = permutations(a, 2)
perm3 = permutations(a, 3)
p_list = []
p_list.extend(list(perm1))
p_list.extend(list(perm2))
p_list.extend(list(perm3))
# p_list = [('a',), ('b',), ('c',), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('a', 'b', 'c'), ('a', 'c', 'b'), ('b', 'a', 'c'), ('b', 'c', 'a'), ('c', 'a', 'b'), ('c', 'b', 'a')]
As you can see, your data structure is not 3rd level: it is only a list of tuples. Now I think it becomes clear that your list comprehension is just iterating over each element inside the tuples, not joining them like:
result = [''.join(n) for n in p_list]
# result = ['a', 'b', 'c', 'ab', 'ac', 'ba', 'bc', 'ca', 'cb', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba']

Generating multiple combinations of strings [duplicate]

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')]

create a dictionary from a list of pairs of elements

I want to create a dictionary using this list of pairs:
pairs = [('a', 'c'), ('b', 'c'), ('b', 'e'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('c', 'e'), ('d', 'c'), ('e', 'c'), ('e', 'f')]
I want to return something like this:
{ "a" : ["c"],
"b" : ["c", "e"],
"c" : ["a", "b", "d", "e"],
"d" : ["c"],
"e" : ["c", "f"],
"f" : []}
So, basically, every element in the pair has to be represented as a key even if they have an empty list. I have tried using this code below:
graph = {}
for k, v in pairs:
if k not in d:
d[k] = []
d[k].append(v)
but it returns only the first element in the pair as key:
{'a': ['c'],
'b': ['c', 'e'],
'c': ['a', 'b', 'd', 'e'],
'd': ['c'],
'e': ['c', 'f']}
pairs = [('a', 'c'), ('b', 'c'), ('b', 'e'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('c', 'e'), ('d', 'c'), ('e', 'c'), ('e', 'f')]
d = {}
for k, v in pairs:
d.setdefault(v, [])
d.setdefault(k, []).append(v)
from pprint import pprint
pprint(d)
Prints:
{'a': ['c'],
'b': ['c', 'e'],
'c': ['a', 'b', 'd', 'e'],
'd': ['c'],
'e': ['c', 'f'],
'f': []}
Adaptations needed to your existing code, which is:
graph = {}
for k, v in pairs:
if k not in d:
d[k] = []
d[k].append(v)
You are calling the output dictionary graph when you initialise it but then d inside the loop. Probably you corrected this already (as otherwise you would be getting an error), but it should obviously be the same (say d) in both cases.
If you want all the values to exist as keys in the dictionary (with empty lists if they do not exist as keys in the input dictionary), then simply add inside the loop the same thing as you are already doing with k, but with v instead:
if v not in d:
d[v] = []

What is the difference between these two List in Python?

I have two Lists in my program list1 and list2 which looks like the following:
list1 = ['ABC',
'ABD',
'ABE',
'ABF',
'ABG',
'ABH',
'ABI',
...]
list2 = [('A', 'B', 'C'),
('A', 'B', 'D'),
('A', 'B', 'E'),
('A', 'B', 'F'),
('A', 'B', 'G'),
('A', 'B', 'I'),
...]
Both the Lists are 2D because they return the same result on the same operation.
list1[0][1] returns 'B'
list2[0][1] also returns 'B'
What is the difference between list1 and list2 if they return the same result? How do I convert list2 in the format of list1?
Thank you.
The first list is list of strings and second list is list of tuples containing strings.
To convert list2 to list1 you can use:
list2 = [('A', 'B', 'C'),
('A', 'B', 'D'),
('A', 'B', 'E'),
('A', 'B', 'F'),
('A', 'B', 'G'),
('A', 'B', 'I'),]
new_list = [''.join(v) for v in list2]
print(new_list)
Output:
['ABC', 'ABD', 'ABE', 'ABF', 'ABG', 'ABI']

Categories