How to use tuples as slice start:end values [duplicate] - python

This question already has answers here:
Python slice how-to, I know the Python slice but how can I use built-in slice object for it?
(6 answers)
Closed 16 days ago.
I need to slice array with arbitrary dimensions by two tuples. I can use slicing, such as a[1:3, 4:6]. But what do i do if 1,3 and 4,6 are tuples?
While a[(1, 3)] works, I tried a[(1, 3), (4, 6)] and it didn't work, I think it ignores (4, 6). And I couldn't figure out how to make something like a[ t1[0] : t1[1], t2[0] : t2[1] ] work depending on how many dimensions there are.
I'd like something like a[(1, 3):(4, 6)], that would also work for higher dimensions, e.g a[(1, 3, 2):(4, 6, 5)]

Extended slice syntax is implemented by the slice type. You can play with this using a simple toy class
class A:
def __getitem__(self, k):
print(k)
Then
>>> A()[1:3, 4:6]
(slice(1, 3, None), slice(4, 6, None))
None is the default 3rd argument if only two are given. So if you have tuples (1, 3) and (4, 6), you can pass explicit slice objects created from them instead of using the extended slicing syntax.
>>> t1, t2 = (1,3), (4, 6)
>>> A()[slice(*t1), slice(*t2)]
(slice(1, 3, None), slice(4, 6, None))

Related

Find out all combinations in a list but cannot be duplicated [duplicate]

This question already has an answer here:
How to get combinations of elements from a list?
(1 answer)
Closed 4 years ago.
Let's say I have a list of four values. I want to find all combinations of two of the values. For example, I would like to get an output like:
((0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3))
As you can see, I do not want repetitions, for example (0, 1) and (1, 0)
This needs to be able to be used with larger numbers, not just 4, and I will have to iterate through all of the combos
I am using Python 3 and Windows, and this would ideally be an inbuilt function, a simple bit of list comprehension code, or something I can import. I have tried making this with range, but I do not know how to exclude the numbers that I have already done from it.
It is very easy
from itertools import combinations
list(combinations([0,1,2,3],2))
Take just the lower triangular matrix if you only need a distinct set
a = [1,2,10,20]
[(a[i], a[j+i+1]) for i in range(len(a)) for j in range(len(a[i+1:]))]
[(1, 2), (1, 10), (1, 20), (2, 10), (2, 20), (10, 20)]

How to create "list of pairs" from an even-length list in python? [duplicate]

This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 1 year ago.
I have a list like this, with an even number of elements:
straight_list = [1, 2, 3, 4, 5, 6]
There are six items in this list. I'd like to group them into three pairs, like this:
paired_list = [(1, 2), (3, 4), (5, 6)]
What's the best way to do this? More generally, given a list with 2*n items, what's the best way to create a list of n pairs? I have come up with the following:
straight_list = [1, 2, 3, 4, 5, 6]
paired_list = []
for i in range(len(straight_list)//2):
j = i*2
pair = (straight_list[j], straight_list[j+1])
paired_list.append(pair)
print(paired_list)
# [(1, 2), (3, 4), (5, 6)]
I also can make it work like this, though it's a tongue-twister:
[tuple(x) for x in list(np.array(straight_list).reshape(len(straight_list)//2,2))]
# [(1, 2), (3, 4), (5, 6)]
Is there a more elegant, functional, and/or "Pythonic" way to create this list of pairs?
(In some ways, this is almost an inverse of this question: "How to make a flat list out of a list of lists?")
How about a simple list comprehension?
paired_list = [(straight_list[i], straight_list[i+1]) for i in range(0, len(straight_list), 2)]

What is a pythonic way to find set of lists which have all common elements?

Say I have a list a=[[1,2],[1.00000001,2.000000001],[2,3],[4,5],[4.0000000002,5.0000006]], and from that I want to get only a=[[1,2],[2,3],[4,5]] because the other lists have all elements close to some other element of the list. How do we do this in Python? Can set be used in some way?
I tried using numpy's allclose function but then we have to compare all n(n-1)/2 pairs in the list a, which is clearly inefficient. Is there a more efficient Pythonic way to do this?
Edit: I just used some integers in the example, the inputs are floats in general.
If the values are like that (i.e. what looks like floating point inaccuracy, you can round the values to the precision you're interested in, then use set() to reduce things to unique tuples:
>>> a=[[1,2],[1.00000001,2.000000001],[2,3],[4,5],[4.0000000002,5.0000006]]
>>> a_r = [tuple(round(v, 2) for v in pair) for pair in a]
[(1, 2), (1.0, 2.0), (2, 3), (4, 5), (4.0, 5.0)]
>>> set(a_r)
{(2, 3), (4, 5), (1, 2)}
For the data sample in your list and the expected result, as you can use Numpy, i'd suggest to use dtype to convert to integer and use numpy.unique.
So, given your list:
a=[[1,2],[1.00000001,2.000000001],[2,3],[4,5],[4.0000000002,5.0000006]]
You can do as follows:
import numpy as np
a_np = np.unique(np.array(a, dtype=np.uint), axis=0)
print(a_np)
# [[1 2]
# [2 3]
# [4 5]]

How to sort a list in order in python? [duplicate]

This question already has answers here:
How to sort a list/tuple of lists/tuples by the element at a given index?
(11 answers)
Closed 2 years ago.
How can I sort a list in order? I have a list of tuples in a list and I need to sort them in order which I want.
list1 = [(2,3,4),(3,4,5),(5,3,2)]
I need to sort them firstly by the second element of tuple, secondly(if the previous were equal) by the third and thirdly by the first. Is there any built-in function to do it?
You can use sorted(iterable,key).
>>>sorted(list1,key=lambda x: (x[1],x[2],x[0])
#[(5, 3, 2), (2, 3, 4), (3, 4, 5)]
If you don't want to use lambda you can use itemgetter.
from operator import itemgetter
sorted(list1,key=itemgetter(1,2,0))
#[(5, 3, 2), (2, 3, 4), (3, 4, 5)]

Readable way to form pairs while available [duplicate]

This question already has answers here:
Iterating over every two elements in a list [duplicate]
(22 answers)
Closed 7 years ago.
I'm trying to turn a list into pairs, but only for as long as possible (i.e. my list can be odd, in that case I want to ignore the last element).
E.g. my input is x = [0, 1, 2, 3, 4], which I would want to turn into [(0, 1), (2, 3)]. Similarly, x = [0, 1, 2, 3, 4, 5] should become [(0, 1), (2, 3), (4, 5)].
What I'm currently doing is [(x[i], x[i+1]) for i in range(0, len(x), 2)]. This breaks, as range(0, len(x), 2) still includes x[-1] if len(x) is odd. Note that something of the form [(l, r) for l, r in ...] would also be preferable, rather than having to fiddle with indices.
Bonus points: Here's some more context. I'm not completely ignoring the last element of an odd sequence, of course. I'm applying a function to each pair, but I do not want to apply this function H to the singleton element. Currently, I'm doing the following:
next_layer = [H(layer[i], layer[i+1]) for i in range(0, len(layer), 2)]
if len(layer) & 1: # if there is a lone node left on this layer
next_layer.append(layer[-1])
An extra elegant solution would incorporate this into the above as well.
Use a zip
This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence.
>>> a = [1, 2, 3, 4, 5]
>>> b = [0, 1, 2, 3, 4, 5]
>>> zip(a[::2], a[1::2])
[(1, 2), (3, 4)]
>>> zip(b[::2], b[1::2])
[(0, 1), (2, 3), (4, 5)]

Categories

Resources