Remove tuples with same elements in two lists - python

a=['-a', ('-c', 'd'), ('-d', 'c')]
b=['-b', ('c', '-d'), ('d', '-c')]
Basicly, for each list, if there is some tuple in another list that has the same elements with it, then remove all of those tuples have this elements from both lists.
(I was using sets instead of tuples, but somewhere in my code got an error
says: unhashable type: 'set', so I changed it to tuples...)
res=[]
for i in a:
for j in b:
if type(i) == tuple and type(j) == tuple:
if i[0] in j and i[1] in j:
res.append(i)
res.append(j)
a,b=list(set(a)-set(res)),list(set(b)-set(res))
print(a,b)
This gives a=['a'],b=['-b'], is there better methods (maybe some simple build in function) to do the same thing ?
More examples
>>>a=['-a', ('-c', 'd'), ('-d', 'c'), ('-d', 'c')]
>>>b=['-b', ('c', '-d'), ('d', '-c'), ('-d', 'c')]
>a=['a'],b=['-b']
>>>a=['-a', ('a', 'b'),('-c', 'd'), ('-d', 'c'), ('-d', 'c')]
>>>b=['-b', ('c', '-d'), ('d', '-c'), ('-d', 'c')]
>a=['a',('a', 'b')],b=['-b']

Use frozenset On the sub items and you will be able to use set.difference:
a = ['-a', ('a', 'b'),('-c', 'd'), ('-d', 'c'), ('-d', 'c')]
b = ['-b', ('c', '-d'), ('d', '-c'), ('-d', 'c')]
seta = {frozenset(i) if isinstance(i, tuple) else i for i in a}
setb = {frozenset(i) if isinstance(i, tuple) else i for i in b}
print(seta - setb, setb - seta)
Prints:
{'-a', frozenset({'a', 'b'})} {'-b'}
I only say this because you said you were using sets before but had issues. You can always turn the frozen sets back to tuple.

Please find the following answer. Basically, you just need to find out duplicates first.
a = ['-a', ('-c', 'd'), ('-d', 'c')]
b = ['-b', ('-c', 'd'), ('d', '-c')]
to_remove = set(a).intersection(set(b))
a = [i for i in a if i not in to_remove or type(i) != tuple]
b = [j for j in b if j not in to_remove or type(j) != tuple]
print a, b

Related

Combinations by list in nested lists in Python

I have a list of the form [['a','b','c','d'], ['a','c','d'], ['b','d','e','f','g','h'], ... ,['c','d','a','b']] and I have to combine the elements of each nested list (separately) in 2-tuples to form a single 2-tuples' list. I have tried to do it with the following code but it only combines the elements of the first list:
def totwotuples(my_list):
for i in range(len(my_list)):
for j in range(len(my_list[i])):
twotuples = itertools.combinations(my_list[i], 2)
return[k for k in twotuples]
How can I iterate over all nested lists? in order to get this expected output (e.g. for first two nested lists): [('a','b'), ('a','c'), ('a','d'), ('b','c'), ('b','d'), ('c','d'), ('a','c'), ('a','d'), ('c','d'), ...]
You can use itertools.chain or itertools.chain.from_iterable to combine the results from sublists.
import itertools
lst = [['a','b','c','d'], ['a','c','d']]
output = itertools.chain.from_iterable(itertools.combinations(sublst, r=2) for sublst in lst)
output = list(output) # convert to a list
print(output) # [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd'), ('a', 'c'), ('a', 'd'), ('c', 'd')]

nested value from nested index python

I am trying to get an output list from nested list based on nested indices.
Input:
list_a = [(a,b,c,d), (f,g), (n,p,x)]
sub_index_a = [(0,2),(1),(0,1)]
Output:
output_list = [(a,c), (g), (n,p)]
list_a = [('a', 'b', 'c', 'd'), ('f', 'g'), ('n', 'p', 'x')]
sub_index_a = [(0, 2), (1,), (0, 1)]
def check(i, e):
r = []
for ee in e:
r.append(list_a[i][ee])
return tuple(r)
outputlist = [check(i, e) for i, e in enumerate(sub_index_a)]
print(outputlist)
This evaluates to
[('a', 'c'), ('g',), ('n', 'p')]
well having ("g") just evaluates to "g",the actual tuple of that would look like ("g",) (tuple(["g"])), same as (1) but I think found a half-decent workaround? Hopefully, this is your desired solution.
list_a = [('a','b','c','d'), ('f','g'), ('n','p','x')]
sub_index_a = [(0,2),(1),(0,1)]
print([tuple([list_a[x][indx] for indx in i]) if type(i) in [tuple, list] else list_a[x][i] for x,i in enumerate(sub_index_a)])
[('a', 'c'), 'g', ('n', 'p')]
if you want everything returned as a tuple you can modify the comprehension to:
print([tuple([list_a[x][indx] for indx in i]) if type(i) in [tuple, list] else tuple([list_a[x][i]]) for x,i in enumerate(sub_index_a)])
[('a', 'c'), ('g',), ('n', 'p')]
note:
if you want everything to be nested (with a single element) you would want a list of lists; E.g. [[0,2],[1],[0,1]]
Use zip and a nested comprehension:
list_a = [("a","b","c","d"), ("f","g"), ("n","p","x")]
sub_index_a = [(0,2),(1,),(0,1)] # note the comma in the second tuple
output_list = [tuple(sub[i] for i in i_s) for sub, i_s in zip(list_a, sub_index_a)]
# [('a', 'c'), ('g',), ('n', 'p')]

How to convert a Python multilevel dictionary into tuples?

I have a multi level dictionary, example below, which needs to be converted into tuples in reverse order i.e, the innermost elements should be used to create tuple first.
{a: {b:c, d:{e:f, g:h, i:{j:['a','b']}}}}
Output should be something like this:
[(j,['a','b']), (i,j), (g,h), (e,f), (d,e), (d,g), (d,i), (b,c), (a,b), (a,d)]
There you go, this will produce what you want (also tested):
def create_tuple(d):
def create_tuple_rec(d, arr):
for k in d:
if type(d[k]) is not dict:
arr.append((k, d[k]))
else:
for subk in d[k]:
arr.append((k, subk))
create_tuple_rec(d[k], arr)
return arr
return create_tuple_rec(d, [])
# Running this
d = {'a': {'b':'c', 'd':{'e':'f', 'g':'h', 'i':{'j':['a','b']}}}}
print str(create_tuple(d))
# Will print:
[('a', 'b'), ('a', 'd'), ('b', 'c'), ('d', 'i'), ('d', 'e'), ('d', 'g'), ('i', 'j'), ('j', ['a', 'b']), ('e', 'f'), ('g', 'h')]

Python : Splitting multidimensional lists

I have a list in the form of
[(u'a1', u'b1'),
(u'a1', u'b2'),
(u'c1', u'c2')]
I want it two be split into two lists/columns like
list1 list2
[(u'a1', [(u'b1'),
(u'a1', (u'b2'),
(u'c1')] (u'c2')]
Conversion of unicode to string would also help!
Also, in another case, I have list in the form of
[(('a', 'c'), -3), (('a', 'd'), -7), (('c', 'd'), -4)]
I need the input in the form of
('a','a','c')
('c','d','d')
(-3,-7,-4)
Any tips?
You could create two new list using lists comprehension:
x=[(u'a1', u'b1'),
(u'a1', u'b2'),
(u'c1', u'c2')]
list1 = [i[0] for i in x]
list2 = [i[1] for i in x]
The second example:
>>> L = [(('a', 'c'), -3), (('a', 'd'), -7), (('c', 'd'), -4)]
>>> zip(*[(a[0], a[1], b) for a, b in L])
[('a', 'a', 'c'), ('c', 'd', 'd'), (-3, -7, -4)]
It first flattens each item and then transposes the list.

Removing duplicates from tuples within a list

I have a list of tuples:
lst = [('a','b'), ('c', 'b'), ('a', 'd'), ('e','f'), ('a', 'b')]
I want the following output list:
output = [('a','b'), ('e','f')]
i.e I want to compare the elements of first tuple with remaining tuples and remove the tuple which contains either one or more duplicate elements.
My attempt:
I was thinking of using for loops, but that wont be feasible once i have very large list. I browsed through following posts but could not get the right solution:
Removing duplicates members from a list of tuples
How do you remove duplicates from a list in whilst preserving order?
If somebody could guide me the right direction, it will be very helpful. Thanks!
Assuming that you want "duplicates" of all elements to be suppressed, and not just the first one, you could use:
lst = [('a','b'), ('c', 'b'), ('a', 'd'), ('e','f'), ('a', 'b')]
def merge(x):
s = set()
for i in x:
if not s.intersection(i):
yield i
s.update(i)
gives
>>> list(merge(lst))
[('a', 'b'), ('e', 'f')]
>>> list(merge([('a', 'b'), ('c', 'd'), ('c', 'e')]))
[('a', 'b'), ('c', 'd')]
>>> list(merge([('a', 'b'), ('a', 'c'), ('c', 'd')]))
[('a', 'b'), ('c', 'd')]
Sets should help:
>>> s = map(set, lst)
>>> first = s[0]
>>> [first] + [i for i in s if not i & first]
[set(['a', 'b']), set(['e', 'f'])]
Or with ifilterfalse:
>>> from itertools import ifilterfalse
>>> s = map(set, lst)
>>> [first] + list(ifilterfalse(first.intersection, s))
[set(['a', 'b']), set(['e', 'f'])]

Categories

Resources