Subtracting a tuples of the list [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 months ago.
Improve this question
I have a list of tuples
lst = [(1,2,3),(1,2,3),(7,8,9)]
And
I want to find the difference between previous tuple from the next like this:
ans = [(0,0,0), (6,6,6)]
How can I do this in Python?

You can iterate over the data and use the sub method from the operator package to subtract the tuples:
from operator import sub
data = [(1,2,3),(1,2,3),(7,8,9)]
diff = [tuple(map(sub, data[i+1], data[i])) for i in range(0, len(data)-1)]
You could also use a for loop instead of the list comprehension if you prefer. The tuple subtraction is from here: Elegant way to perform tuple arithmetic

from functools import reduce, partial
from operator import sub
my_list = [(1,2,3),(1,2,3),(7,8,9)]
diff_list = list(map(partial(reduce, lambda a, b: tuple(map(sub, a, b))), zip(my_list[1:], my_list)))
To break it down:
zip(my_list[1:], my_list)
This creates a new iterator which yields iterables consisting of every next element of the list followed by the previous.
partial(reduce, lambda a, b: tuple(map(sub, a, b)))
This creates a function which when given an iterable whose elements consist of tuples, will return a new tuple containing the difference between the first and the second tuples. It could be more tuples, but in our case, we only ever pass to this function an iterable consisting of two tuples, it will always do what we want.

Try:
lst = [(1, 2, 3), (1, 2, 3), (7, 8, 9)]
out = [tuple(b - a for a, b in zip(t1, t2)) for t1, t2 in zip(lst, lst[1:])]
print(out)
Prints:
[(0, 0, 0), (6, 6, 6)]

Related

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

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))))

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.

Python test if list items are far apart [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have a list in python that might look something like this:
list_example = [1,2,20,21,22]
As you can see, all the numbers are close to their adjacent list items, except for the jump between 2 and 20.
How would I get Python to notice this larger jump and store the list item's index?
You can use zip() to iterate through every i and i+1 element, and then compute the difference between the two adjacent elements.
for a, b in zip(list_example, list_example[1:]):
diff = b - a
if diff > 10:
print("Jump between %d and %d" % (a, b))
But then, it is up to you to define what is exactly a "jump".
If you need the index, you can make use of enumerate():
for i, (a, b) in enumerate(zip(list_example, list_example[1:])):
...
You could get the average distance between elements and then output those indices where the distance to the last element is larger than that average.
>>> lst = [1,2,20,21,22]
>>> avg_dst = sum(abs(a-b) for a, b in zip(lst, lst[1:])) / (len(lst)-1)
>>> [i for i in range(1, len(lst)) if abs(lst[i] - lst[i-1]) > avg_dst]
[2]
You need a set number that is the number that will set a jump off.
This means looping over comparing the current number with its neighbour and alerting whenever the numbers have a difference of your set jump number.
This is assuming your list is already sorted.
Assuming that the values are arranged in ascending order (like your example), you could created a sorted list of (DIFF, INDEX) pairs.
xs = [1, 2, 20, 21, 22]
pairs = sorted((xs[i] - xs[i-1], i) for i in range(1, len(xs)))
print(pairs) # [(1, 1), (1, 3), (1, 4), (18, 2)]

Store more than 1 value in python array? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I would like to store more than 1 value in a python array(I am open to any other data structure too).
For example :
array[1][2][3] = 1 # (this is what I am able to do now)
But later I also get the value 2, now instead of storing it in another array using the same indices, I want to be able to do this :
array[1][2][3] = 1,2
But I dont want to concatenate the existing result like in a string, and split the string to get the individual values.
Is there a way of doing this without having to introduce another dimension to the array?
edit : I want a neater way to store 2 values in the same cell.
Thanks
I would use defaultdict for this:
from collections import defaultdict
array = defaultdict(list)
array[(1,2,3)].append(1)
array[(1,2,3)].append(2)
Now array at position (1,2,3) is a list containing 1 and 2
If understand correctly, you can store new list with values you need in array[1][2][3] instead of single value:
array[1][2][3] = [1] # instead of = 1
array[1][2][3].append(2) # now it's [1, 2]
array[1][2][3].extend([3,4]) # now it's [1, 2, 3, 4]
all_values = array[1][2][3] # no another dimensions uses to get values
If you know all the contents a priori you may use a tuple. Here I will create pairs of numbers (n, n+1) and store them in a list:
>>> l = [(n,n+1) for n in xrange(0,4)]
>>> l
[(0, 1), (1, 2), (2, 3), (3, 4)]
If you decide you want to append another value, you can. Assume you want to append 3 to the tuple (1,2):
>>> l[1] = l[1] + (3,)
>>> l
[(0, 1), (1, 2, 3), (2, 3), (3, 4)]
Tuples are immutable, so they're faster than lists for construction, but you can't make changes to an instantiated tuple - you must replace it. If you're fairly certain your data won't change, use a tuple. If it will (and often), use a list.
Edit
If you want the values from the tuple, you can do the following:
>>> tup = l[0]
>>> tup
(0, 1)
>>> x, y = tup
>>> x
0
>>> y
1
>>> t, u = l[2] # alternatively
>>> t
2
>>> u
3
array[1][2][3] = 1,2
Seems like you want to have a list in array[1][2][3], which you could actually do with
array[1][2][3] = [1,2]
or alternatively, as already mentionned by others with variations of
array[1][2][3] = []
array[1][2][3].append(1)
array[1][2][3].extend([2])
Mind the fact that use of t-uples is also possible
array[1][2][3] = (1,2)
But in this case, you won't be able to extend your "list" nor to modify its content (t-uples are indeed constant arrays, in size as well as in content.).
Is there a way of doing this without having to introduce another
dimension to the array?
Well... this requirement seems rather antagonistic with your previous one.
array[1][2][3] = 1,2
suggests that your are able to differentiate between "array[1][2][3][0]" (=1) and "array[1][2][3][1]" (=2). So, unless I don't understand your question, the short answer is "no" :)

Why doesn't addition broadcast over tuples? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
E.g., why can't I do:
(0,1) + (2,2)
and get:
(2,3)
as a result?
Because the + operator is used to make a new tuple that is the combination of two other tuples. That is just how Python was designed.
To do what you want, you can use zip and a generator expression:
>>> t1 = (0,1)
>>> t2 = (2,2)
>>> tuple(x + y for x, y in zip(t1, t2))
(2, 3)
>>>
'+' operator concatenate tuples . if you want to sum tuples item you can use:
tuple(sum(x) for x in zip((0,1),(2,2)))
or
tuple(map(sum,zip((0,1),(2,2))))
Its because of you add tow tuple and + operation for tuples concatenate them ! you can use map and zip functions for that :
>>> map(sum,zip((0,1),(2,2)))
[2, 3]
or use a generator :
>>> tuple(i+j for i,j in zip((0,1),(2,2)))
(2, 3)
and a better way with operator.add:
>>> from operator import add
>>> map(add,(0,1),(2,2))
[2, 3]
Since Python thinks of tuples as lists that are immutable, adding two tuples is just like adding two lists. So, just as adding two lists will concatenate them:
>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
adding two tuples will also concatenate them:
>>> (1, 2) + (3, 4)
(1, 2, 3, 4)
You can create a new tuple that consists of the sum of each pair with a few of Python's built-in functions:
>>> tuple(map(sum, zip((0, 1), (2, 2))))
(2, 3)
This works by using zip() on the two tuples to make a list of pairs:
>>> zip((0, 1), (2, 2))
[(0, 2), (1, 2)]
And using map() to apply sum() on each element of that list, to get a list of sums:
>>> map(sum, zip((0, 1), (2, 2)))
[2, 3]
And, finally, using tuple() to turn that from a list into a tuple.
Element-wise addition is a more specialized operation than concatenation. Fewer tuples could be added together: what would ('a','b') + (1,2,) equal?
Or ('a', 'b') + (1,2,3) for that matter?
Since concatenation is arguably the more commonly desired operation, and importantly, well defined for all tuples, it makes sense that addition of tuples performs concatenation.

Categories

Resources