Removing duplicates from a list of tuples in python - 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']]

Related

how to find tuple with repeated elements in 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

How to convert tuple to list with float and string values

I have a list of tuples like this:
tuple_list = [(['MATH120'], 3.665, 0.4737615433949868), (['GER'], 3.4566666666666666, 0.3967146329542181), (['FREE'], 3.415636363636364, 0.450256863026264), ([''], 0.041607963246554365, 0.38832820111766464)]
and what I want to do is convert this to:
result = [['MATH120', 3.665, 0.4737615433949868],['GER', 3.4566666666666666, 0.3967146329542181],['FREE', 3.415636363636364, 0.450256863026264]]
meaning that I want to convert it into a list of 3 pairs and delete the whole tuple if the list it has inside has only elements that are empty and delete also the empty strings that might exist in the tuple for example if it was like this:
tuple_list = [(['MATH120',''], 3.665, 0.4737615433949868), (['GER','',''], 3.4566666666666666, 0.3967146329542181), (['FREE'], 3.415636363636364, 0.450256863026264), ([''], 0.041607963246554365, 0.38832820111766464)]
I want it to turn to the same as previous:
result = [['MATH120', 3.665, 0.4737615433949868],['GER', 3.4566666666666666, 0.3967146329542181],['FREE', 3.415636363636364, 0.450256863026264]]
I tried doing this in order to put them just in list:
result= [list(map(list, l)) for l in tuple_list]
but I kept on getting error because of the float values:
TypeError: 'float' object is not iterable
If your data is always regular like that, and you only want the first element in the inner lists, then simply:
>>> [[x, y, z] for [x, *_], y, z in data]
[['MATH120', 3.665, 0.4737615433949868], ['GER', 3.4566666666666666, 0.3967146329542181], ['FREE', 3.415636363636364, 0.450256863026264], ['', 0.041607963246554365, 0.38832820111766464]]
FINAL EDIT:
Since you've clarified that they are empty strings, we can do something a little nicer:
>>> [ [*filter(None, lst), a, b] for lst, a, b in data if any(lst) ]
[['MATH120', 3.665, 0.4737615433949868], ['GER', 3.4566666666666666, 0.3967146329542181], ['FREE', 3.415636363636364, 0.450256863026264]]
>>>
Which I actually think is quite nicely declarative
result= [ [e for e in l if e] + list(t) for l, *t in tuple_list if any(l) ]
[e in t[0] if e] removes empty strings from a sublist; then the remaining elements of the tuple are appended; but if there are no non-empty elements in a list (any(t[0]) is False) then this tuple is skipped.
The reason you get this error is because when you call map(list, l), l refers to an inner tuple (E.G. (['MATH120'], 3.665, 0.4737615433949868)), and those floats cannot be converted to a list directly. I recommend doing something like the following:
for listIndex in range(tuple_list):
tuple_list[listIndex] = list(tuple_list[listIndex]) # Converts inner tuples to list
for element in inner_tuple:
if isinstance(element, list): # checks if element inside tuple is list
#do logic on list that you need
If your first element is always a list in your tuple, just account for it in more hardcoded way. It will only work with data in same format as examples you presented, list(tuple(list(...), ...), ...)
result_list = []
for x in tuple_list:
temp_tuple = []
if (len(x[0]) == 1 and x[0][0] == '') or len(x[0]) == 0:
continue
for y in x[0]:
if y == '':
continue
temp_tuple.append(y)
for y in range(1, len(x)):
temp_tuple.append(x[y])
result_list.append(temp_tuple)
I tested and result on examples and output was like you asked.
This solution is not one-line solution like other answers. But I personally prefer to avoid one-line loops in python if I can. That makes it easier for me to read it.
You just had one level too much. Use this:
result = [list(x) for x in tuple_list]
or
result = list(map(list, tuple_list))

How to iterate a zip list and print each index of it after joining to lists of the same size?

Given the variables:
X = ['a', 'b', 'c']
Y = [1, 2, 3]
complete the following statement:
[print(pair) for pair in ...]
so as to print to the screen pairs of elements from X and Y which occupy the same position in the index.
I know I can make a join X and Y and make a list using list(zip(X,Y)) but the adding that in the statement gives an empty list.
I can't solve this problem using the form required any help?
thanks!
Not really clear what you're trying to achieve. If you need to print pairs, zip works, i.e.
for pair in zip(X, Y):
print(pair)
[print(pair) for pair in ...] is list comprehension, this is made to create lists, not to print data:
pairs_list = [pair for pair in zip(X, Y)] # don't do this
which is simply pairs_list = list(zip(X, Y)). Does this make sense to you?
Using list comprehensions to leverage a sideeffect (like printing something) is frowned upon. If you dont need a list, don't build one.
[print(pair) for pair in zip(X,Y)] # no need to list(zip(...))
will result in lots on None ... because the return value of print() is None.
Use a simple loop:
for p in zip(X,Y):
print(p)

Python, Combining lists within a dict

Is it possible to combine lists in a dict to a new key?
For example, i have a dict setup
ListDict = {
'loopone': ['oneone', 'onetwo', 'onethree'],
'looptwo': ['twoone', 'twotwo', 'twothree'],
'loopthree': ['threeone', 'threetwo', 'threethree']}
I want a new key called 'loopfour' which contains the lists from 'loopone', 'looptwo', and 'loopthree'
So its list would look like
['oneone', 'onetwo', 'onethree', 'twoone', 'twotwo', 'twothree', 'threeone', 'threetwo', 'threethree']
and can be called using ListDict['four'] and return the combined list
Just use two for clauses in a list comprehension. Note however, dictionaries are not ordered so the resulting list can come out in a different order than they were originally put in the dictionary:
>>> ListDict['loopfour'] = [x for y in ListDict.values() for x in y]
>>> ListDict['loopfour']
['oneone', 'onetwo', 'onethree', 'twoone', 'twotwo', 'twothree', 'threeone', 'threetwo', 'threethree']
If you want it ordered then:
>>> ListDict['loopfour'] = [x for k in ['loopone', 'looptwo', 'loopthree'] for x in ListDict[k]]
>>> ListDict['loopfour']
['oneone', 'onetwo', 'onethree', 'twoone', 'twotwo', 'twothree', 'threeone', 'threetwo', 'threethree']

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