Remove zipped pairs with same entries in Python list - python

I have a list of zipped pairs (for example A)
A = [(0, 0), (0, 1), (0, 6), (0, 7), (1, 3), (1, 1), (2, 2)]
What's the best way in which I can remove all pairs where the first and the second entries equal each other (and create a new list)?
In the above example (A), the pairs that I wish to remove are (0, 0), (1, 1) and (2, 2). In this example, I wish the new list to look like this.
A_new = [(0, 1), (0, 6), (0, 7), (1, 3)]

You can use simple list comprehension with if clause that returns True for all unequal pairs that you want to keep:
>>> A = [(0, 0), (0, 1), (0, 6), (0, 7), (1, 3), (1, 1), (2, 2)]
>>> [(x, y) for x, y in A if x != y]
[(0, 1), (0, 6), (0, 7), (1, 3)]

using filter, it takes a judge function as first parameter to tell what element to keep and the iterable list as second parameter, lambda defines an anonymous function.
A_new = filter(lambda x: x[0] != x[1], A)

you can do it with list comprehension:
a = [(0, 0), (0, 1), (0, 6), (0, 7), (1, 3), (1, 1), (2, 2)]
final = [k for k in a if k[0] != k[1]]
Output:
print(final)
>>> [(0, 1), (0, 6), (0, 7), (1, 3)]

Related

get rid of repeated self values and keep only one out of (2,0) (0,2)?

according to #KellyBundy answer, I'd like to get rid of repeated self-values (2, 2), (0, 0)
and keep only either (2, 1) or (1, 2), keep only either (1, 0) or (0, 1) and get rid of repeated (0, 2)
[(0, 2), (2, 2), (2, 1), (1, 2), (2, 2), (0,2), (2, 2), (2, 1), (1, 0), (0, 0), (0, 1)]
out of this
from itertools import pairwise, chain
lis = [(0, [75, 1, 30]), (1, [41, 49, 55]), (2, [28, 53, 45])]
found = [*chain(*(pairwise(a) for *a, a[1:] in lis))]
print(found)
mylist = [(0, 2), (2, 2), (2, 1), (1, 2), (2, 2), (0,2), (2, 2), (2, 1), (1, 0), (0, 0), (0, 1)]
seen = set()
final = [(i,j) for i,j in mylist if i!=j and (i+j, abs(i-j)) not in seen and not seen.add((i+j, abs(i-j)))]
we filter on ((i+j), abs(i-j))
if you really need a one liner, we can use a lambda function
list(filter(lambda e, seen=set(): e[0]!=e[1] and (e[0]+e[1], abs(e[0]-e[1])) not in seen and not seen.add((e[0]+e[1], abs(e[0]-e[1]))), mylist))
i+j and abs(i-j) here are the sum and absolute difference. It makes the logic simpler since (x,y) and (y,x) have the same absolute difference and the same sum.
(i+j, abs(i+j)) is a tuple containing both the sum and absolute difference
seen here is a python set, which can be used to efficiently check if something already exists within it.

How to make a list of the coordinates of all columns and rows

Suppose I have a n x n grid, and I want a function that generates a list of all columns and rows by taking n as the input, in python. By a list of columns, I mean each column is represented as its own list, with elements being coordinates of the elements in the column. (Or each column could be a set of coordinates, that would work too)
I could do this using two list comprehensions,
x = [[ (i, j) for j in range(n)] for i in range(n)] + [[ (i, j) for i in range(n)] for j in range(n)]
With n=3 this produces a list with 9 elements, each of which is a list of 3 coordinates.
x = [[(0, 0), (0, 1), (0, 2)], [(1, 0), (1, 1), (1, 2)], [(2, 0), (2, 1), (2, 2)], [(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)]]
I was wondering if there is a cleaner way to do the same thing, maybe using itertools or a similar module.
Not exactly sure if this is what you're looking for but you could try itertools.product
For example
>>> from itertools import product
>>> n = 3
>>> list(product(range(n),range(n)))
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
>>> [list(product(range(n),range(n)))[n*i:n*i+n] for i in range(n)]
[[(0, 0), (0, 1), (0, 2)], [(1, 0), (1, 1), (1, 2)], [(2, 0), (2, 1), (2, 2)]]
>>> [list(product(range(n),range(n)))[i::n] for i in range(n)]
[[(0, 0), (1, 0), (2, 0)], [(0, 1), (1, 1), (2, 1)], [(0, 2), (1, 2), (2, 2)]]

How to create a sequence of two values?

I have a list with different combinations, i.e:
list1 = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
I also have another list, in my case one looking like:
list2 = [1,1]
What I would like to do is to take the two values of list2, put them together as (1,1), and compare them with the elements in list1, then returning the index. My current attempt is looking like this:
def return_index(comb):
try:
return comb_leaves.index(comb)
except ValueError:
print("no such value")
Unfortunately, it cant find it, because it's not a sequence. Anyone with any good idea of how to fix this?
You are confusing "sequence" with "tuple". Lists and tuples are both sequences. Informally, a sequence is anything that has a length and supports direct indexing in addition to being iterable. A range object is considered to be a sequence too for example.
To create a two element tuple from any other sequence, use the constructor:
test_element = tuple(list_2)
list3 = tuple(list2)
print(list3 in list1) #Check if it exists.
Try this:
list1 = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
list2 = [1, 1]
def return_index(comb):
try:
return list1.index(tuple(comb))
except ValueError:
print("Item not found")
print(return_index(list2)) # 4
With this line:
list1.index(tuple(list2))
Convert list2 into a tuple from a list. list1's elements are tuples, so to make the comparison, list2 needs to be a tuple. tuple(list2) turns [1, 1] into (1, 1) (the same type as the elements of list1).
list1 = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
list2 = [1,1]
tup2 = tuple(list2)
list1.append(tup2)
print('list1:',list1)
print('index:', list1.index(tup2))
will give this:
list1: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (1, 1)]
index: 4
Not sure if unconditionally adding tup2 is what you want.
Maybe you ask for the index, if the 2nd list is in list1:
list1 = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]list2 = [1,1]
tup2 = tuple(list2)
if tup2 in list1:
print('index:', list1.index(tup2))
else:
print('not found')
That gives:
index: 4
the index function returns the first element that matches.

Remove duplicate consecutive tuples from list?

Say, I have a list like below:
[(2, 1), (1, 0), (1, 0), (1,0), (2,1), (2, 1)]
I want to remove duplicate consecutive tuples. So in above example, it should return:
[(2, 1), (1, 0), (2, 1)]
You can use itertools.groupby:
from itertools import groupby
x = [(2, 1), (1, 0), (1, 0), (1, 0), (2, 1), (2, 1)]
x_grouped = [i for i, j in groupby(x)]
# [(2, 1), (1, 0), (2, 1)]
You can use a generator that only yields elements that are not equal to the preceding one:
def filter_consecutive_duplicates(it):
prev = object() # sentinel object, won't be equal to anything else
for elem in it:
if elem != prev:
yield elem
prev = elem
Demo:
>>> list(filter_consecutive_duplicates([(2, 1), (1, 0), (1, 0),(1,0),(2,1), (2, 1)]))
[(2, 1), (1, 0), (2, 1)]
a=[(2, 1), (1, 0), (1, 0), (1,0), (2,1), (2, 1)]
a=[elem for count,elem in enumerate(a) if elem!=a[count-1] or count==0]
How about this list comprehension

Need a clever way to create a large list for a pygame/pyOpenGL project

Basically I need lists of rows that go like this:
[0,0]
[1,0],[0,1]
[2,0],[1,1],[0,2]
[3,0],[2,1],[1,2],[0,3]
[4,0],[3,1],[2,2],[1,3],[0,4]
up to an arbitrary number of elements and then back down
[4,1],[3,2],[2,3],[1,4]
[4,2],[3,3],[2,4]
[4,3],[3,4]
[4,4]
I'm just wanting all of these pairs in one large list of lists, so I can iterate over the pairs in the order they appear above for isometric rendering.
the output would look like this
[ [ (0,0) ], [ (1,0),(0,1) ], [ (2,0), (1,1), (0,2) ]....]etc
It's not entirely clear what generalization you're looking for, but IIUC there are lots of ways you can do it. One is to build each sublist from the previous list (adding one to each subelement and avoiding duplicates), but another is to work directly from the arithmetic:
def sherwood(n):
N = 2*n+1
for i in range(N):
low, high = max(0, i-n), min(i, n)
w = list(range(low, high+1))
yield zip(w[::-1], w)
gives me
>>> out = list(sherwood(2))
>>> for x in out: print(x)
[(0, 0)]
[(1, 0), (0, 1)]
[(2, 0), (1, 1), (0, 2)]
[(2, 1), (1, 2)]
[(2, 2)]
>>> out = list(sherwood(4))
>>> for x in out: print(x)
[(0, 0)]
[(1, 0), (0, 1)]
[(2, 0), (1, 1), (0, 2)]
[(3, 0), (2, 1), (1, 2), (0, 3)]
[(4, 0), (3, 1), (2, 2), (1, 3), (0, 4)]
[(4, 1), (3, 2), (2, 3), (1, 4)]
[(4, 2), (3, 3), (2, 4)]
[(4, 3), (3, 4)]
[(4, 4)]
def create_lists(max_num):
retlist = []
for i in range(max_num+1):
i_list = []
for j in range(i, -1, -1):
i_list.append((j, i-j))
retlist.append(i_list)
for i in range(1, max_num+1):
i_list = []
for j in range(i, max_num+1):
i_list.append((max_num+i-j, j))
retlist.append(i_list)
return retlist

Categories

Resources