Convert Set of Tuples to a List of Lists | Python - python

Generating unique combinations by using set() over itertools.
Outputs a set of tuples, each originating from their invocations respectively.
Instead, I now want to convert this result into a list.
import itertools
my_list = ['A', 'B', 'C']
pairs = set(itertools.combinations(my_list, 2))
print(pairs)
>>> {('A', 'C'), ('B', 'C'), ('A', 'B')}
Instead, I would like:
[['A', 'C'], ['B', 'C'], ['A', 'B']]

a =[[item for item in pair] for pair in pairs]
print(a)
returns
[['B', 'C'], ['A', 'C'], ['A', 'B']]

Related

concat two lists in a list of lists

Is it possible to concat two lists in a list of lists?
From:
listA = ['a', 'b', 'c']
listB = ['A', 'B', 'C']
listFull = listA + listB
To:
print(listFull)
[['a', 'A'],['b', 'B'],['c', 'C']]
List comprehension using zip()
listFull = [list(x) for x in zip(listA, listB)]
print(listFull)
You can also use map() without looping
listFull = list(map(list, zip(listA, listB)))
[['a', 'A'],['b', 'B'],['c', 'C']]
there are several ways to achieve this.
you either need atleast 1 for loop or a map/zip combination.
both possibilities here:
listA = ['a', 'b', 'c']
listB = ['A', 'B', 'C']
#1
listFull =[]
for i in range(len(listA)):
listFull.append([listA[i],listB[i]])
print(listFull)
# output [['a', 'A'], ['b', 'B'], ['c', 'C']]
#2
listfull2 = list(map(list,zip(listA,listB)))
print(listfull2)
# output [['a', 'A'], ['b', 'B'], ['c', 'C']]
"Concatenate" is what the + does, which puts one list after another. What you're describing is called a "zip" operation, and Python has exactly that function built-in.
zip returns an iterable, so if you want a list, you can call list on it.
print(list(zip(listA, listB)))
# Output: [('a', 'A'), ('b', 'B'), ('c', 'C')]

python get groups of combinations that each member appear only once

I'm trying to get groups of permutations/combinations (r=2) that each member appear only once
I used python 'combinations' package to have the combinations.
For example: the members are: a,b,c,d.
The combinations are: [a,b],[a,c],[a,d],[b,c],[b,d]...
My desired output is:
[ {[a,b],[c,d]},{[a,c],[b,d]},{[a,d],[b,c]}...]
I would like to know what is the terminology for that case and if there is already implementation for that.
Thanks.
Here's a way to do it:
from itertools import combinations, chain
l = ['a','b','c','d']
c = list(combinations(l,2))
[set(i) for i in list(combinations(c,2)) if (len(set(l) & set(chain(*i))) == len(l))]
[{('a', 'b'), ('c', 'd')}, {('a', 'c'), ('b', 'd')}, {('a', 'd'), ('b', 'c')}]
Explanation
You can use itertools.combinations twice, in order to get all the 2 tuple combinations from:
list(combinations(l,2))
[('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
And select only those whose set of elements intersect with that of the original list, len(set(l) & set(chain(*i))) == len(l)) for every possible combination.
You can find the permutations up to r and then filter the results:
def combinations(d, d1, r, _c = [], _start=[]):
if len([i for b in _c for i in b]) == len(d1):
yield _c
else:
for i in d:
if i not in _start:
if len(_start+[i]) < r:
yield from combinations(d, d1, r, _c, _start=_start+[i])
else:
_d = sorted(_start+[i])
yield from combinations([i for i in d if i not in _d], d1,r, _c+[_d], [])
data = ['a', 'b', 'c', 'd']
_r = list(combinations(data, data, 2))
new_d = [a for i, a in enumerate(_r) if a not in _r[:i]]
Output:
[[['a', 'b'], ['c', 'd']], [['a', 'c'], ['b', 'd']], [['a', 'd'], ['b', 'c']], [['b', 'c'], ['a', 'd']], [['b', 'd'], ['a', 'c']], [['c', 'd'], ['a', 'b']]]

Extracting Unique String Combinations from List of List in Python

I'm trying to extract all the unique combinations of strings from a list of lists in Python. For example, in the code below, ['a', 'b','c'] and ['b', 'a', 'c'] are not unique, while ['a', 'b','c'] and ['a', 'e','f'] or ['a', 'b','c'] and ['d', 'e','f'] are unique.
I've tried converting my list of lists to a list of tuples and using sets to compare elements, but all elements are still being returned.
combos = [['a', 'b', 'c'], ['c', 'b', 'a'], ['d', 'e', 'f'], ['c', 'a', 'b'], ['c', 'f', 'b']]
# converting list of list to list of tuples, so they can be converted into a set
combos = [tuple(item) for item in combos]
combos = set(combos)
grouping_list = set()
for combination in combos:
if combination not in grouping_list:
grouping_list.add(combination)
##
print grouping_list
>>> set([('a', 'b', 'c'), ('c', 'a', 'b'), ('d', 'e', 'f'), ('c', 'b', 'a'), ('c', 'f', 'b')])
How about sorting, (and using a Counter)?
from collections import Counter
combos = [['a', 'b', 'c'], ['c', 'b', 'a'], ['d', 'e', 'f'], ['c', 'a', 'b'], ['c', 'f', 'b']]
combos = Counter(tuple(sorted(item)) for item in combos)
print(combos)
returns:
Counter({('a', 'b', 'c'): 3, ('d', 'e', 'f'): 1, ('b', 'c', 'f'): 1})
EDIT: I'm not sure if I'm correctly understanding your question. You can use a Counter to count occurances, or use a set if you're only interested in the resulting sets of items, and not in their uniqueness.
Something like:
combos = set(tuple(sorted(item)) for item in combos)
Simply returns
set([('a', 'b', 'c'), ('d', 'e', 'f'), ('b', 'c', 'f')])
>>> set(tuple(set(combo)) for combo in combos)
{('a', 'c', 'b'), ('c', 'b', 'f'), ('e', 'd', 'f')}
Simple but if we have same elements in the combo, it will return wrong answer. Then, sorting is the way to go as suggested in others.
How about this:
combos = [['a', 'b', 'c'], ['c', 'b', 'a'], ['d', 'e', 'f'], ['c', 'a', 'b'], ['c', 'f', 'b']]
print [list(y) for y in set([''.join(sorted(c)) for c in combos])]

Python create many-to-many relationships from a list

I have a list, say terms = ['A', 'B', 'C', 'D']
Which is the best way to create a list-of-lists or list-of-tuples of many-to-many relationships like this;
[['A','B'],['A','C'],['A','D'],['B','C'],['B','D'],['C','D']]
Using itertools.combinations():
from itertools import combinations
list(combinations(terms, r=2))
Demo:
>>> from itertools import combinations
>>> terms = ['A', 'B', 'C', 'D']
>>> list(combinations(terms, r=2))
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]
These are tuples, not lists, but that's easily remedied if that is a problem:
>>> map(list, combinations(terms, r=2))
[['A', 'B'], ['A', 'C'], ['A', 'D'], ['B', 'C'], ['B', 'D'], ['C', 'D']]

How can I make a list from a list of tuples ?

if I have a list of tuple like:
L=[(('a','b','c','d'),2),(('f','e','d','a'),3)]
I want to make a list that like:
L1=[['a','b','c','d'],['f','e','d','a']]
this is what I did:
L1=[]
for item in L:
for(letter,integer) in item:
L1.append(list(letter))
print(L1)
but it comes up with error say that there are too many values to unpack
what's wrong with my code?
What's useful here is a list comprehension:
L1 = [list(letters) for (letters, number) in L]
This iterates over each pair in your list, taking the letters tuple of each pair and converting it to a list. It then stores each result as the element of a new list.
You did:
for item in L:
for(letter,integer) in item:
L1.append(list(letter))
print(L1)
However, item is already a tuple and there's no need to iterate through it. What you want is
for letter, integer in L:
L1.append(list(letter))
Or...
for item in L:
letter, integer = item
L1.append(list(letter))
you may try:
L1 = [list(i[0]) for i in L]
Your problem is in this line:
for(letter,integer) in item:
This will (try to) iterate over item, which is a 2-element tuple. Replace it by:
(letter,integer) = item
And it will work. There are more concise ways of doing that, of course, but this should get you started.
There are several options to do that, one of them is to map your list by getting first element, eg. like this:
>>> from operator import itemgetter
>>> map(list, map(itemgetter(0), L))
[['a', 'b', 'c', 'd'], ['f', 'e', 'd', 'a']]
The other one is to use list comprehensions:
>>> [list(item[0]) for item in L]
[['a', 'b', 'c', 'd'], ['f', 'e', 'd', 'a']]
or lambda:
>>> map(lambda x: list(x[0]), L)
[['a', 'b', 'c', 'd'], ['f', 'e', 'd', 'a']]
But maybe you do not need a list and tuple will do. In such case the examples are simpler:
>>> from operator import itemgetter
>>> map(itemgetter(0), L)
[('a', 'b', 'c', 'd'), ('f', 'e', 'd', 'a')]
>>> [item[0] for item in L]
[('a', 'b', 'c', 'd'), ('f', 'e', 'd', 'a')]
>>> map(lambda x: x[0], L)
[('a', 'b', 'c', 'd'), ('f', 'e', 'd', 'a')]

Categories