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
Related
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)]]
I find source code of itertools.combinations() function in python. It looks like this.
def combinations(iterable, r):
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = list(range(r))
print(indices)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
print(indices)
yield tuple(pool[i] for i in indices)
I have tuples like this:
pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
I need to generate foursomes of all possible combinations, but with condition, that there will be always only two same numbers in list. So in this case this 3 list I want to generate:
((0, 1), (0, 2), (1, 3), (2, 3))
((0, 1), (0, 3), (1, 2), (2, 3))
((0, 2), (0, 3), (1, 2), (1, 3))
What I realy need is to update code of generation combinations, because in my real app I need to generate 23-nties from 80 tuples. Generation and filtering after it would take a lot of time, thats why I need to catch problem in part of generation.
You can use itertools.combinations and then filter the result using collections.Counter:
from collections import Counter
import itertools as it
pairs = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
result = filter(
lambda x: max(Counter(it.chain(*x)).values()) < 3,
it.combinations(pairs, 4)
)
print(list(result))
Output:
[((0, 1), (0, 2), (1, 3), (2, 3)),
((0, 1), (0, 3), (1, 2), (2, 3)),
((0, 2), (0, 3), (1, 2), (1, 3))]
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.
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)]
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