Generate all combinations from multiple lists in python - python

I have a dataset which contains multiple lists each having different number of elements. For eg.
list1 = ['a','b','c']
list2 = ['d','e']
list3 = ['f','g','h','i']
I want to generate all possible unique combinations from these lists with the following conditions:
The number of elements in one combination should be 5
Minimum of 1 element from each list.
How would I go about doing this?

I think this will do it (a lot of these steps could be combined but keeping them in to show steps)
Create a new list with all items in
list4 = list1 + list2 + list3
And another list to iterate through them to find all 5 combinations (you didn't specify about order or replacement so have a read here and change as necessary)
list5 = list(itertools.combinations(list4, 5))
Then remove the items that don't have an element from each list.
[i for i in list5 if any(j in list1 for j in i) and any(j in list2 for j in i) and any(j in list3 for j in i)]
So in one line it could be:
[i for i in itertools.combinations(list1 + list2 + list3, 5) if any(j in list1 for j in i) and any(j in list2 for j in i) and any(j in list3 for j in i)]

I support #Ghost Ops's answer.
itertools.product gave me the result I was looking for & in the easiest way.
Example:
from itertools import product
Suit = [u"\u2666", u"\u2665", u"\u2663", u"\u2660"]
Card = ['A','K','Q','J','10','9','8','7','6','5','4','3','2']
FullDeck = list(product(Card, Suit))
for i in FullDeck:
print(i)
Which Returns:
('A', '♦')
('A', '♥')
('A', '♣')
('A', '♠')
('K', '♦')
('K', '♥')
('K', '♣')
('K', '♠')
('Q', '♦')
('Q', '♥')
('Q', '♣')
('Q', '♠')
('J', '♦')
('J', '♥')
('J', '♣')
('J', '♠')
('10', '♦')
('10', '♥')
('10', '♣')
('10', '♠')
('9', '♦')
('9', '♥')
('9', '♣')
('9', '♠')
('8', '♦')
('8', '♥')
('8', '♣')
('8', '♠')
('7', '♦')
('7', '♥')
('7', '♣')
('7', '♠')
('6', '♦')
('6', '♥')
('6', '♣')
('6', '♠')
('5', '♦')
('5', '♥')
('5', '♣')
('5', '♠')
('4', '♦')
('4', '♥')
('4', '♣')
('4', '♠')
('3', '♦')
('3', '♥')
('3', '♣')
('3', '♠')
('2', '♦')
('2', '♥')
('2', '♣')
('2', '♠')

Related

Deck of cards using zip

Im trying to make a deck of cards using zip,
but what i got is the object code?
"<zip object at 0x0000025763A32200>, <zip object at 0x0000025763A32240>,...."
suits = ['diamond','club','heart','spade']
value = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']
deck = [zip(suit, val) for val in value for suit in suits]
print(deck)
How do i make it as a list of tuples? (using zip)
print(deck)
output :
[('A','diamond'),('A','club')....('K','diamond')]
Is it really necessary to use zip? You can get what you want just by not using zip and leaving your code as it is, saving a tuple(val,suit), not zipping them:
>>> deck = [(val,suit) for val in value for suit in suits]
>>> print(deck)
[('A', 'diamond'), ('A', 'club'), ('A', 'heart'), ('A', 'spade'), ('2', 'diamond'), ('2', 'club'), ('2', 'heart'), ('2', 'spade'), ('3', 'diamond'), ('3', 'club'), ('3', 'heart'), ('3', 'spade'), ('4', 'diamond'), ('4', 'club'), ('4', 'heart'), ('4', 'spade'), ('5', 'diamond'), ('5', 'club'), ('5', 'heart'), ('5', 'spade'), ('6', 'diamond'), ('6', 'club'), ('6', 'heart'), ('6', 'spade'), ('7', 'diamond'), ('7', 'club'), ('7', 'heart'), ('7', 'spade'), ('8', 'diamond'), ('8', 'club'), ('8', 'heart'), ('8', 'spade'), ('9', 'diamond'), ('9', 'club'), ('9', 'heart'), ('9', 'spade'), ('10', 'diamond'), ('10', 'club'), ('10', 'heart'), ('10', 'spade'), ('J', 'diamond'), ('J', 'club'), ('J', 'heart'), ('J', 'spade'), ('Q', 'diamond'), ('Q', 'club'), ('Q', 'heart'), ('Q', 'spade'), ('K', 'diamond'), ('K', 'club'), ('K', 'heart'), ('K', 'spade')]
Remember, if you want the order by value the right order in your tuple must be (val,suit), and not (suit,val)
With this simple form you don't need any extra module.
zip won't work for this, but you can use itertools.product:
>>> import itertools
>>> deck = list(itertools.product(value, suits))
>>> print(deck)
[('A', 'diamond'), ('A', 'club'), ('A', 'heart'), ('A', 'spade'), ('2', 'diamond'), ('2', 'club'), ('2', 'heart'), ('2', 'spade'), ('3', 'diamond'), ('3', 'club'), ('3', 'heart'), ('3', 'spade'), ('4', 'diamond'), ('4', 'club'), ('4', 'heart'), ('4', 'spade'), ('5', 'diamond'), ('5', 'club'), ('5', 'heart'), ('5', 'spade'), ('6', 'diamond'), ('6', 'club'), ('6', 'heart'), ('6', 'spade'), ('7', 'diamond'), ('7', 'club'), ('7', 'heart'), ('7', 'spade'), ('8', 'diamond'), ('8', 'club'), ('8', 'heart'), ('8', 'spade'), ('9', 'diamond'), ('9', 'club'), ('9', 'heart'), ('9', 'spade'), ('10', 'diamond'), ('10', 'club'), ('10', 'heart'), ('10', 'spade'), ('J', 'diamond'), ('J', 'club'), ('J', 'heart'), ('J', 'spade'), ('Q', 'diamond'), ('Q', 'club'), ('Q', 'heart'), ('Q', 'spade'), ('K', 'diamond'), ('K', 'club'), ('K', 'heart'), ('K', 'spade')]

List Comprehension Appending Index with Number Range on List of Lists

I am looking for a list comprehension in adding a range of numbers based on index position in a list of lists while keeping the second index alone.
search_keys = [('1', 'B'), ('1', 'K'), ('1', 'Y')]
Desired Result:
new_search_keys = [('11', 'B'), ('12', 'B'), ('13', 'B'), ('14', 'B'), ('15', 'B')...
...('11', 'K'), ('12', 'K'), ('13', 'K'), ('14', 'K'), ('15', 'K')...
...('11', 'Y'), ('12', 'Y'), ('13', 'Y'), ('14', 'Y'), ('15', 'Y')...]
My attempt brings a TypeError: 'type' object is not subscriptable:
new_search_keys = [search_keys[i][0] + list(range[1,9]) for i in range(len(search_keys))]
This should solve your problem:-
new_search_keys = [(search_keys[i][0] +str(j), search_keys[i][1]) for i in range(len(search_keys)) for j in range(1,9)]
Output:-
[('11', 'B'), ('12', 'B'), ('13', 'B'), ('14', 'B'), ('15', 'B'), ('16', 'B'), ('17', 'B'), ('18', 'B'), ('11', 'K'), ('12', 'K'), ('13', 'K'), ('14', 'K'), ('15', 'K'), ('16', 'K'), ('17', 'K'), ('18', 'K'), ('11', 'Y'), ('12', 'Y'), ('13', 'Y'), ('14', 'Y'), ('15', 'Y'), ('16', 'Y'), ('17', 'Y'), ('18', 'Y')]

How to get the unique values from column on string data with file handling in python

this is how my data looks :ALL THESE DATA ARE IN SINGLE COLUMN
#columnA
(8,8)
(6,7)(7,7)(7,6)
(2,12)(12,3)(3,4)(4,12)(12,12)
(14,14)
(1,1)(1,12)(12,2)(2,2)(2,4)
(6,8)(8,8)(8,12)
(6,6)(6,3)(3,14)
(1,14)(14,14)(14,1)(1,1)(1,2)
(1,1)(1,14)
(2,2)(2,15)(15,5)(5,5)(5,16)
(1,11)(11,1)(1,2)(2,2)(2,14)
(5,5)(5,1)
(12,2)(2,2)(2,10)(10,10)
(9,9)(9,4)(4,4)
(13,13)
(1,1)
(11,14)(14,14)
for i in range(len(data)):
x.iloc[i]=data.iloc[i].unique()
output is to replace the duplicate values and find unique:
How about storing all the data in a list and find the set of the list.
for instance, if I have a list of tupples or list of lists in the form:
list = [(1,1), (2,3), (2,3), (1,3), (1,3), (1,1)]
set_of_list = set(list)
>>> {(1,3), (2,3), (1,1)}
IIUC, use pandas.Series.str.findall with explode and unique:
uniq = df['columnA'].str.findall("(\d+),(\d+)").explode().unique()
uniq
Output:
array([('8', '8'), ('6', '7'), ('7', '7'), ('7', '6'), ('2', '12'),
('12', '3'), ('3', '4'), ('4', '12'), ('12', '12'), ('14', '14'),
('1', '1'), ('1', '12'), ('12', '2'), ('2', '2'), ('2', '4'),
('6', '8'), ('8', '12'), ('6', '6'), ('6', '3'), ('3', '14'),
('1', '14'), ('14', '1'), ('1', '2'), ('2', '15'), ('15', '5'),
('5', '5'), ('5', '16'), ('1', '11'), ('11', '1'), ('2', '14'),
('5', '1'), ('2', '10'), ('10', '10'), ('9', '9'), ('9', '4'),
('4', '4'), ('13', '13'), ('11', '14')], dtype=object)

Make combination inside list of tuple

I was working on some other question . I have below list
[(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
Output should be below
[('1', 'abc'), ('2', 'abc'), ('3', 'abc'), ('4', 'xyz'), ('5', 'xyz'), ('6', 'xyz')]
My attempt is
First i unlist the list inside it
l1=[ tuple(i[0])+(i[1],) for i in l ]
print (l1)
[('1', '2', '3', 'abc'), ('4', '5', '6', 'xyz')]
Then tried product from itertools , but it is not giving me the required result. Problem is 'abc' is getting splited in 'a','b','c' using product.
from itertools import product
[ list(product(i[:-1],i[-1])) for i in l1 ]
[[('1', 'a'),
('1', 'b'),
('1', 'c'),
('2', 'a'),
('2', 'b'),
('2', 'c'),
('3', 'a'),
('3', 'b'),
('3', 'c')],
[('4', 'x'),
('4', 'y'),
('4', 'z'),
('5', 'x'),
('5', 'y'),
('5', 'z'),
('6', 'x'),
('6', 'y'),
('6', 'z')]]
Use list comprehension:
L=[(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
In: [ (n,s) for l,s in L for n in l ]
Out:
[('1', 'abc'),
('2', 'abc'),
('3', 'abc'),
('4', 'xyz'),
('5', 'xyz'),
('6', 'xyz')]
As you can write:
rslt=[]
for l,s in L:
for n in l:
rslt.append((n,s))
product from itertools is working as intended. The issue is that Python strings are iterable, so product is iterating through the elements of the string. If you want to treat the string as a single element, you can put it into a list and feed the list to product
You can use itertools.product as long as you wrap the string in an iterable so that it is handled as a single element of an iterable rather than iterated.
from itertools import product
data = [(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
combos = [combo for a, b in data for combo in product(a, [b])]
print(combos)
# [('1', 'abc'), ('2', 'abc'), ('3', 'abc'), ('4', 'xyz'), ('5', 'xyz'), ('6', 'xyz')]
You can use list comprehensions:
ls = [(['1', '2', '3'], 'abc'), (['4', '5', '6'], 'xyz')]
ls_new = [(a,b) for n,b in ls for a in n]
print(ls_new)

How to delete similar value from a list and print the remaining

list =[('1', '5'), ('3', '5'), ('4', '5'), ('5', '1'), ('5', '3'), ('5', '4')]
above is a generated list now i want to write only (5,1) for (1,5) and (5,1) too same with the other values.
Desired output
list = [('5', '1'), ('5', '3'), ('5', '4')]
Add the item to the new list if its reverse is not also in the list, or the item is larger than its reverse.
newlist = []
for item in oldlist:
rev = item[::-1]
if (not (rev in oldlist)) or (item > rev)
newlist.append(item)
l = [('1', '5'), ('3', '5'), ('4', '5'), ('5', '1'), ('5', '3'), ('5', '4')]
s=set()
for e in l:
if e[0] >= e[1]:
s.add(e)
else:
s.add((e[1], e[0]))
l = list(s)
Note: it doesn't preserve the order. If that is important:
s=set(); l2 = []
for e in l:
if e[0] < e[1]:
e = (e[1], e[0])
if not e in s:
s.add(e)
l2.append(e)
li =[('1', '5'), ('3', '5'), ('4', '5'), ('5', '1'), ('5', '3'), ('5', '4')]
gen = ((a,b) if a>b else (b,a) for a,b in li)
lu = []
[lu.append(y) for y in gen if y not in lu]
print lu
If order isn't important, you can achieve this with the list and set functions in a one liner like the following:
orig_list =[('1', '5'), ('3', '5'), ('4', '5'), ('5', '1'), ('5', '3'), ('5', '4')]
modified_list = list(set([(t[0], t[1]) if t[0] > t[1] else (t[1], t[0]) for t in orig_list]))
Concise, if a bit dense.
my_list = [('1', '5'), ('3', '5'), ('4', '5'), ('5', '1'), ('5', '3'), ('5', '4')]
new_list = [(a, b) if (a > b) else (b, a) for a, b in my_list]
result = list(set(new_list))

Categories

Resources