Finding unique list in list of list of tuples [duplicate] - python

This question already has answers here:
Get unique items from list of lists? [duplicate]
(3 answers)
Closed 2 years ago.
I have a list of lists of tuples:
x = [[(0,0),(0,1)],[(1,2),(2,3)],[(0,0),(0,1)],[(1,2),(2,3)]]
I want all the unique lists present in the list x
My output should be:
x=[[(0,0),(0,1)],[(1,2),(2,3)]]
I tried using x=list(set(x)) but it gives error: 'list is not hashable', I also tried using numpy.unique but it does not give desired output. How can I implement this?

list as mutable and hence can not be used as an element to a set. However, you can type-cast the list to tuple which are immutable, and then you can get unique elements using set. Here I am using map() to covert all sub-lists to tuple:
>>> x = [[(0,0),(0,1)],[(1,2),(2,3)],[(0,0),(0,1)],[(1,2),(2,3)]]
>>> set(map(tuple, x))
{((1, 2), (2, 3)), ((0, 0), (0, 1))}
To type-cast the set back to list and change back nested tuple to list, you can further use map() as:
>>> list(map(list, set(map(tuple, x))))
[[(1, 2), (2, 3)], [(0, 0), (0, 1)]]

i would do something like this:
x = [[(0,0),(0,1)],[(1,2),(2,3)],[(0,0),(0,1)],[(1,2),(2,3)]]
result = []
for i in x:
if not i in result:
result.append(i)
print(result)
maybe it is not the fastest way but certainly it is the simpler.
Otherwise you can use the most "cool" way, you can use sets. Sets are like lists that don't allow equal elements.
x = x = [[(0,0),(0,1)],[(1,2),(2,3)],[(0,0),(0,1)],[(1,2),(2,3)]]
result = list(map(list,set(map(tuple,x))))

Related

Question about combing the sum() with zip()

a=[1,2,3]
b=[3,4,5,2]
c=[60,70,80]
sum(zip(a,b,c),())
what's the logic for the sum function here? why does it return a single tuple? especially why the following won't work
sum(zip(a,b,c))
The sum() function, simply concatenates items together with "+" and an initial value. Likewise, the zip() function produces tupled items together. Explicitly:
list(zip(a,b,c)) # [(1, 3, 60), (2, 4, 70), (3, 5, 80)]
sum([1,2,3],0) # 0 + 1 + 2 + 3
sum(zip(a,b,c),()) # () + (1,3,60) + (2,4,70) + (3,5,80)
Hope this helps explain the sum() and zip() functions. zip() can be tricky to see what it is doing since it produces an iterator instead of an answer. If you want to see what zip() does, wrap it in a list().
The sum(zip(a,b,c)) fails because the default initial value is 0. Hence, python tried to do 0 + (1,3,60) + ..., which fails because a 0 cannot be added to a tuple.
The other answers are useful in resolving any confusion, but perhaps the result you might be looking for is achieved by doing this:
sum(a+b+c)
because the + operator when applied to lists, concatenates them into a single list whereas zip does not
zip() does not do what you think it does. sum() will add the items of its input and return the result. In your case, you want to sum numbers from 3 lists. zip() returns tuples containing elements of the same index from the inputs, and when the result of this is passed to sum, it concatenates the tuples, leaving you with your undesired result. The fix is to use itertools.chain to combine the lists, then use sum to sum the numbers in those lists.
To show exactly how zip() works, an example should be useful:
a = ["a", "b", "c"]
b = [1, 2, 3]
list(zip(a, b)) -> [('a', 1), ('b', 2), ('c', 3)]
zip returned a generator of tuples (converted to a list here), each containing the element from each input that corresponds to the index of the tuple in the result, i.e, list(zip(a, b))[index] == (a[index], b[index])
What you want is this:
sum(itertools.chain(a, b, c))
EDIT: Make sure to import itertools first.

Removing coordinates from list on python [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 6 years ago.
I have created a list full of "coordinates" in Python: L1 = [(1,2), (5,6), (-1,-2), (1,-2), etc..].
If I wanted to remove all items in the list which contained negative numbers, how would I do this?
I've tried:
for (a,b) in L1:
if a < 0 or b < 0:
L1.remove(a,b)
But it isn't working. Would very much appreciate any help.
Jack
You cannot change something while you're iterating it. The results are weird and counter-intuitive, and nearly never what you want. In fact, many collections explicitly disallow this (e.g. sets and dicts).
Instead, iterate over a copy (for e in a[:]: ...) or, instead of modifying an existing list, filter it to get a new list containing the items you want ([e for e in a if ...]). Note that in many cases, you don't have to iterate again to filter, just merge the filtering with the generation of the data.
L2 = []
for (a,b) in L1:
if a >= 0 and b >= 0:
L2.append((a,b))
L1 = L2
print L1
You can filter using a list comprehension:
>>> coords = [(1, 2), (5, 6), (-1, -2), (1, -2)]
>>> [coord for coord in coords
... if not any(number < 0 for number in coord)]
[(1, 2), (5, 6)]

How to sort list of tuples using both elements of tuple?

I want to sort by first element in tuple, and, if first element for some tuples is equal, by second element.
For example, I have [(5,1),(1,2),(1,1),(4,3)] and I want to get [(1,1),(1,2),(4,3),(5,1)]
How can I do it in pythonic way?
d = [(5,1),(1,2),(1,1),(4,3)]
print(sorted(d,key=lambda x:(x[0],x[1])))
if you want better performance use itemgetter
import operator
l = [(5,1),(1,2),(1,1),(4,3)]
print(sorted(l, key=operator.itemgetter(0,1))
You don't really need to specify the key since you want to sort on the list item itself.
>>> d = [(5,1),(1,2),(1,1),(4,3)]
>>> sorted(d)
[(1, 1), (1, 2), (4, 3), (5, 1)]
Remember, Sorted method will return a list object. In this case d still remains unsorted.
If you want to sort d you can use
>>>d.sort()
Hope it helps

Array to tuple conversion python [duplicate]

This question already has answers here:
Create (L[i], L[i+1]) tuple list from list L [duplicate]
(4 answers)
Closed 7 years ago.
I have an array that looks like this
[1,2,3,4,5]
and I would like a list of tuples that looks like this:
[(1,2),(2,3),(3,4),(4,5)]
What is the most convenient way to do this in python?
Thanks!
zip( a[:-1], a[1:] )
see help(zip) or the website documentation of zip.
Since zip limits itself to the shorter sequence,
zip(a, a[1:])
works too.
EDIT:
Steven brought up the interesting point that if a is very long, doing the implicit copy to get the separate pyObject that is a[1:] is problematic. In this case, you might want to use numpy and its options to get a view on the same data with but a offset.
This can be done using list comprehension and list slicing, you iterate over the elements upto len(a) - 1 and on each iteration slice the elements form current_index and the element next to it.
a = [1,2,3,4,5]
b = [tuple(a[i:i+2]) for i in range(len(a)-1)]
print b
>>> [(1, 2), (2, 3), (3, 4), (4, 5)]

Iterate through tuple values python

I have a list like
[(1, 3), (6, 7)]
and a string
'AABBCCDD'
I need to get the result AABCD.
I know I can get the integers form the tuple with nameOfTuple[0][0] yielding 1.
I also know that I can get the chars form the string with nameOfString[0] yielding A.
My question is, how do I iterate through two arguments in the tuple, in order to save the integers (to a list maybe) and then get the chars from the string?
In [1]: l = [(1, 3), (6, 7)]
In [2]: s = 'AABBCCDD'
In [3]: ''.join(s[start-1:end] for (start,end) in l)
Out[3]: 'AABCD'
Here, pairs of indices from l are assigned to start and end, one pair at a time. The relevant portion of the string is then extracted using s[start-1:end], yielding a sequence of strings. The strings are then merged using join().

Categories

Resources