how to find tuple with repeated elements in python? - python

I have a list in the format
unique_edges=[('SLT2', 'SDP1'),('GCD7', 'ATG34'),('MTH1', 'MTH1'),('ADY2', 'ADY2')]
and I need to use list comprehension (one line of code) to move the tuples with the same element twice (like ('MTH1', 'MTH1')) to a new list.
I'm thinking I will need to use something like
homo_dimers = list(map(tuple,unique_edges))
but I don't know how to use these functions to search for repeated elements within one tuple.

List comprehension to find tuples with same element:
homo_dimers = [(a, b) for a, b in unique_edges if a == b]
print(homo_dimers)
Prints:
[('MTH1', 'MTH1'), ('ADY2', 'ADY2')]
Or if your tuples contain more than 2 elements:
homo_dimers = [t for t in unique_edges if len(set(t)) == 1]

You can use if statements in list comprehensions:
unique_edges = [('SLT2', 'SDP1'), ('GCD7', 'ATG34'), ('MTH1', 'MTH1'),
('ADY2', 'ADY2')]
print([i for i in unique_edges if i[0] == i[1]])

homo_dimers = [i for i in unique_edges if i[0]==i[1]]
Output
[('MTH1', 'MTH1'), ('ADY2', 'ADY2')]

def move_from_list(item, old, new): #becaue we cant call multiple functions in a list comprehension line we create one funtion to move a tupil
old.remove(item)
new.append(item)
unique_edges=[('SLT2', 'SDP1'),('GCD7', 'ATG34'),('MTH1', 'MTH1'),('ADY2', 'ADY2')] #input list
homo_dimers=[]#empty list to fill with all the non-unique tupils
[move_from_list((a,b), unique_edges, homo_dimers) for a, b in unique_edges if a == b ] # the list comprehension line
print(homo_dimers) #[('MTH1', 'MTH1'), ('ADY2', 'ADY2')]
print(unique_edges) #[('SLT2', 'SDP1'), ('GCD7', 'ATG34'), ('ADY2', 'ADY2')]
I may have misunderstood the question. this code asumes you want to remove the non unique tupils from the list "unique_edges" AND add them to homo_dimers

Related

I want to compare list of two cities and if list B cities are not present in list A then should append in list A using python

A=['mumbai','delhi','jaipur']
B=['mumbai','kolkata','pune']
I want to compare list A and list B and if list B cities are not in list A then we should able to append those cities in list A
One more way to do the same but not by using the for loop.
difference_between_lists = list(set(B) - set(A))
A += difference_between_lists
You loop through list B and check if the item in list B is in list A. If it is, don't do anything, if it isn't, append it to list A.
for i in B:
if not i in A:
A.append(i)
You can also do this using list comprehension
C = [i for i in B if not i in A]
print(A+C)
You can also use sets and do the union.
setA = set(A)
setB = set(B)
print(setB.union(setA))

Changing elements of list to string

I have a list [['user44'],['user204'],['user355'],['user395'],['user452']]
I want to convert it to [ 'user44', 'user204' , 'user355', 'user395', 'user452']
Any help on this?
Assuming userXYZ is always a string
lst = [['user44'],['user204'],['user355'],['user395'],['user452']]
lst1 = [y for x in lst for y in x]
print(lst1)
output
['user44', 'user204', 'user355', 'user395', 'user452']
Every element of the list is a list itself, with one element.
You can take that element and create a new list using list comprehension.
new_list=[elem[0] for elem in old_list]
This will go over all elements of the list (which are themselves, lists), and extract the strings into a new list.
This will allow for use encase you need to join more than 1 list.
x = [''.join(x[i] for i in range(len(x)))]

Removing duplicates from a list of tuples in python

I have a list of tuples, and I want to remove duplicate tuples. Something like this.
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
I want the output something like this :
y = [['aaron','jeng'],['sdf','wqd']]
How can I do that in an easy way? I can write code to do that, but is there any inbuilt function for this?
Edit 1 : As everyone has suggested, I'm sorry to call them tuples. I meant a list of lists. Thank You.
Your x value does not contain a list of tuples, but a list of lists. If it did contain a list of tuples:
x = [('aaron','jeng'),('sdf','wqd'),('aaron','jeng')]
out = set([i for i in x])
print(list(out))
[('aaron', 'jeng'), ('sdf', 'wqd')]
That's a list of lists... But no matter, you can use a temporary set to make sure there are no repeats:
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
seen = set() # store here the visited tuples
y = [e for e in x if tuple(e) not in seen and not seen.add(tuple(e))]
# [['aaron', 'jeng'], ['sdf', 'wqd']]
If you convert your inner lists to tuples upfront it will have a considerably better performance.
If you don't need to preserve the order, then just convert the inner lists to tuples and turn your x to a set().
This would be easy with a list of tuples, you would simply need set(x). Since your list is a list of lists, and not a list of tuples, you can convert them first:
set(tuple(i) for i in x)
returns:
{('aaron', 'jeng'), ('sdf', 'wqd')}
Or, if you want to reconvert to a list of lists as you had it:
[list(t) for t in (set(tuple(i) for i in x))]
# [['aaron', 'jeng'], ['sdf', 'wqd']]
You can use enumerate and any:
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
new_x = [[a, b] for i, [a, b] in enumerate(x) if not any(c == b for _, c in x[:i])]
Output:
[['aaron', 'jeng'], ['sdf', 'wqd']]
You do not have tuples, you have lists inside lists.
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
uniques = list (set ( tuple(a) for a in x))
Is a generator expression fed into a set thats then fed to a list resulting in
[('aaron', 'jeng'), ('sdf', 'wqd')]
What about converting to a dict , Because dict can have unique keys :
x = [['aaron','jeng'],['sdf','wqd'],['aaron','jeng']]
print({tuple(i):i for i in x}.values())
output:
[['aaron', 'jeng'], ['sdf', 'wqd']]

Matching elements between lists in Python - keeping location

I have two lists, both fairly long. List A contains a list of integers, some of which are repeated in list B. I can find which elements appear in both by using:
idx = set(list_A).intersection(list_B)
This returns a set of all the elements appearing in both list A and list B.
However, I would like to find a way to find the matches between the two lists and also retain information about the elements' positions in both lists. Such a function might look like:
def match_lists(list_A,list_B):
.
.
.
return match_A,match_B
where match_A would contain the positions of elements in list_A that had a match somewhere in list_B and vice-versa for match_B.
I can see how to construct such lists using a for-loop, however this feels like it would be prohibitively slow for long lists.
Regarding duplicates: list_B has no duplicates in it, if there is a duplicate in list_A then return all the matched positions as a list, so match_A would be a list of lists.
That should do the job :)
def match_list(list_A, list_B):
intersect = set(list_A).intersection(list_B)
interPosA = [[i for i, x in enumerate(list_A) if x == dup] for dup in intersect]
interPosB = [i for i, x in enumerate(list_B) if x in intersect]
return interPosA, interPosB
(Thanks to machine yearning for duplicate edit)
Use dicts or defaultdicts to store the unique values as keys that map to the indices they appear at, then combine the dicts:
from collections import defaultdict
def make_offset_dict(it):
ret = defaultdict(list) # Or set, the values are unique indices either way
for i, x in enumerate(it):
ret[x].append(i)
dictA = make_offset_dict(A)
dictB = make_offset_dict(B)
for k in dictA.viewkeys() & dictB.viewkeys(): # Plain .keys() on Py3
print(k, dictA[k], dictB[k])
This iterates A and B exactly once each so it works even if they're one-time use iterators, e.g. from a file-like object, and it works efficiently, storing no more data than needed and sticking to cheap hashing based operations instead of repeated iteration.
This isn't the solution to your specific problem, but it preserves all the information needed to solve your problem and then some (e.g. it's cheap to figure out where the matches are located for any given value in either A or B); you can trivially adapt it to your use case or more complicated ones.
How about this:
def match_lists(list_A, list_B):
idx = set(list_A).intersection(list_B)
A_indexes = []
for i, element in enumerate(list_A):
if element in idx:
A_indexes.append(i)
B_indexes = []
for i, element in enumerate(list_B):
if element in idx:
B_indexes.append(i)
return A_indexes, B_indexes
This only runs through each list once (requiring only one dict) and also works with duplicates in list_B
def match_lists(list_A,list_B):
da=dict((e,i) for i,e in enumerate(list_A))
for bi,e in enumerate(list_B):
try:
ai=da[e]
yield (e,ai,bi) # element e is in position ai in list_A and bi in list_B
except KeyError:
pass
Try this:
def match_lists(list_A, list_B):
match_A = {}
match_B = {}
for elem in list_A:
if elem in list_B:
match_A[elem] = list_A.index(elem)
match_B[elem] = list_B.index(elem)
return match_A, match_B

Python: How to convert a list to a list of tuples?

for example, i have a list below,
['Visa', 'Rogers', 'Visa']
if i want to convert it to a list of tuples, like
[('Visa',), ('Rogers',), ('Visa',)]
How can I convert it?
>>> [(x,) for x in ['Visa', 'Rogers', 'Visa']]
[('Visa',), ('Rogers',), ('Visa',)]
simple list comprehension will do the trick. make sure to have the , to specify single item tuples (you will just have the original strings instead)
Doing some kind of operation for each element can be done with map() or list comprehensions:
a = ['Visa', 'Rogers', 'Visa']
b = [(v,) for v in a]
c = map(lambda v: (v,), a)
print(b) # [('Visa',), ('Rogers',), ('Visa',)]
print(c) # [('Visa',), ('Rogers',), ('Visa',)]
Please keep in mind that 1-element-tuples are represented as (value,) to distinguish them from just a grouping/regular parantheses

Categories

Resources