Related
Alright. So I've been through some SO answers such as Find an element in a list of tuples in python and they don't seem that specific to my case. And I am getting no idea on how to use them in my issue.
Let us say I have a list of a tuple of tuples; i.e. the list stores several data points each referring to a Cartesian point. Each outer tuple represents the entire data of the point. There is an inner tuple in this tuple which is the point exactly. That is, let us take the point (1,2) and have 5 denoting some meaning to this point. The outer tuple will be ((1,2),5)
Well, it is easy to figure out how to generate this. However, I want to search for an outer tuple based on the value of the inner tuple. That is I wanna do:
for y in range(0, 10):
for x in range(0, 10):
if (x, y) in ###:
print("Found")
or something of this sense. How can this be done?
Based on the suggestion posted as a comment by #timgen, here is some pseudo-sample data.
The list is gonna be
selectPointSet = [((9, 2), 1), ((4, 7), 2), ((7, 3), 0), ((5, 0), 0), ((8, 1), 2)]
So I may wanna iterate through the whole domain of points which ranges from (0,0) to (9,9) and do something if the point is one among those in selectPointSet; i.e. if it is (9, 2), (4, 7), (7, 3), (5, 0) or (8, 1)
Using the data structures that you currently are, you can do it like this:
listTuple = [((1,1),5),((2,3),5)] #dummy list of tuples
for y in range(0, 10):
for x in range(0, 10):
for i in listTuple:#loop through list of tuples
if (x, y) in listTuple[listTuple.index(i)]:#test to see if (x,y) is in the tuple at this index
print(str((x,y)) , "Found")
You can make use of a dictionary.
temp = [((1,2),3),((2,3),4),((6,7),4)]
newDict = {}
# a dictionary with inner tuple as key
for t in temp:
newDict[t[0]] = t[1]
for y in range(0, 10):
for x in range(0, 10):
if newDict.__contains__((x,y)):
print("Found")
I hope this is what you are asking for.
Make a set from the two-element tuples for O(1) lookup.
>>> data = [((1,2),3),((2,3),4),((6,7),4)]
>>> tups = {x[0] for x in data}
Now you can query tups with any tuple you like.
>>> (6, 7) in tups
True
>>> (3, 2) in tups
False
Searching for values from 0 to 9:
>>> from itertools import product
>>> for x, y in product(range(10), range(10)):
... if (x, y) in tups:
... print('found ({}, {})'.format(x, y))
...
found (1, 2)
found (2, 3)
found (6, 7)
If you need to retain information about the third number (and the two-element inner tuples in data are unique) then you can also construct a dictionary instead of a set.
>>> d = dict(data)
>>> d
{(1, 2): 3, (2, 3): 4, (6, 7): 4}
>>> (2, 3) in d
True
>>> d[(2, 3)]
4
all I have a list of list of tuple here
A =[[(1, 52), (1, 12), (-1, -1)],[(-1, 23), (1, 42), (-1, -1)],[(1, -1), (-1, -1), (1, 42)]]
I wanted get the tuples containing the max values in second element of the tuple, column-wise.
I tried accessing columns like this
A[:,2]
But I get the error
TypeError: list indices must be integers, not tuple
Thanks in advance, Please let me know if you need any other information
Edit 1:
Desired output:
[(1, 52),(1, 42),(1, 42)]
[max(a,key=lambda x:x[1]) for a in zip(*A)]
output:
[(1, 52), (1, 42), (1, 42)]
Let me know if this works for you I will explain the answer.
You can access columns like this..
>>> list(zip(*A)[0])
[(1, 52), (-1, 23), (1, -1)]
>>> list(zip(*A)[1])
[(1, 12), (1, 42), (-1, -1)]
Explanation
zip https://docs.python.org/3/library/functions.html#zip
>>> x=[1,2,3]
>>> y=['a','b','c']
>>> z=['first','second','third']
>>> zip(x,y,z)
[(1, 'a', 'first'), (2, 'b', 'second'), (3, 'c', 'third')]
Now imagine x,y,z being the rows you had in A. By zip(rows) it returns 1st elements, 2nd elements, 3rd elements etc... There by returning us columns of the rows we passed.
Note: zip acts on multiple arguments passed in so we need to send multiple rows like x,y,z separately, not like [x,y,z] as a list. That is done by *A which separates the rows and passes to zip.
Now we got different columns
maxhttps://docs.python.org/3/library/functions.html#max
max(1,2) #Will return 2
max(cars,lambda x:x.speed) #Will give you the fastest car
max(cars,lambda x:x.capacity) #Will give you the biggest passenger car
max(tups,lambda x:x[1]) #Will give you the tuple with biggest 2nd element
List Comprehensionhttps://docs.python.org/3/tutorial/datastructures.html#list-comprehensions
A=[1,2,3]
[x**2 for x in A] #Will give you [1,4,9]
[x**3 for x in A] #Will give you [1,8,27]
Finally
[max(a,key=lambda x:x[1]) for a in zip(*A)]
Will give you max for each column!
You can try this:
A =[[(1, 52), (1, 12), (-1, -1)],[(-1, 23), (1, 42), (-1, -1)],[(1, -1), (-1, -1), (1, 42)]]
new_A = [max(a, key=lambda x: x[-1]) for a in zip(*A)]
Output:
[(1, 52), (1, 42), (1, 42)]
A is a list is lists of tuples. Basic Python does not recognised multiple-element subscripting, although Numpy and similar modules extend it. Your subscript expression :,2 is therefore interpreted as a tuple whose first element is a lice and whose second element is an integer, which (as the message explains) is not acceptable as a list index.
Unfortunately, "the tuples containing the max values in second element of the tuple, column-wise" isn't a terribly good description of the actual desired result.
I presume the answer you would like is [(1, 52), (1, 42), (1, 42)].
One relatively simple way to achieve this is to sort each of the sub-lists separately, taking the last element of each. this could be spelled as
result = [sorted(x, key=lambda z: z[1])[-1] for x in A]
The key argument to the sorted function ensures that each list is sorted on its second element, the
[-1] subscript takes the last (and therefore highest) element of the sorted list, and the for x in A ensure that each element of the output corresponds to an element (i.e., a list of three tuples) of the input.
I've got a list
a = [(1,2),(1,4),(2,6),(1,8),(3,6),(1,10),(1,6)]
If I say that:
for x in a:
if x[0]==1:
print x
I get the expected result : (1,2) (1,4) (1,8) (1,10) (1,6)
However I want to remove all the occurrences of all the tuples in the format (1,x),So
for x in a:
if x[0]==1:
a.remove(x)
I thought that all the occurences should be removed.However when i say
Print a
I get [(1,4),(2,6),(3,6),(1,6)]
Not all the tuples were removed. How do I do it.??
Thanks
I'd use list comprehension:
def removeTuplesWithOne(lst):
return [x for x in lst if x[0] != 1]
a = removeTuplesWithOne([(1,2),(1,4),(2,6),(1,8),(3,6),(1,10),(1,6)])
For me it's more pythonic than built-in filter function.
P.S. This function does not change your original list, it creates new one. If your original list is huge, i'd probably use generator expression like so:
def removeTuplesWithOne(lst):
return (x for x in lst if x[0] != 1)
This isn't the same approach as yours but should work
a = filter(lambda x: x[0] != 1, a)
You can use list comprehension like this, to filter out the items which have 1 as the first element.
>>> original = [(1, 2), (1, 4), (2, 6), (1, 8), (3, 6), (1, 10), (1, 6)]
>>> [item for item in original if item[0] != 1]
[(2, 6), (3, 6)]
This creates a new list, rather than modifying the existing one. 99% of the time, this will be fine, but if you need to modify the original list, you can do that by assigning back:
original[:] = [item for item in original if item[0] != 1]
Here we use slice assignment, which works by replacing every item from the start to the end of the original list (the [:]) with the items from the list comprehension. If you just used normal assignment, you would just change what the name original pointed to, not actually modify the list itself.
You can do it with a generator expression if you're dealing with huge amounts of data:
a = [(1,2),(1,4),(2,6),(1,8),(3,6),(1,10),(1,6)]
# create a generator
a = ((x,y) for x, y in a if x == 1)
# simply convert it to a list if you need to...
>>> print list(a)
[(1, 2), (1, 4), (1, 8), (1, 10), (1, 6)]
Is there a python builtin that does the same as tupler for a set of lists, or something similar:
def tupler(arg1, *args):
length = min([len(arg1)]+[len(x) for x in args])
out = []
for i in range(length):
out.append(tuple([x[i] for x in [arg1]+args]))
return out
so, for example:
tupler([1,2,3,4],[5,6,7])
returns:
[(1,5),(2,6),(3,7)]
or perhaps there is proper pythony way of doing this, or is there a generator similar???
I think you're looking for zip():
>>> zip([1,2,3,4],[5,6,7])
[(1, 5), (2, 6), (3, 7)]
have a look at the built-in zip function http://docs.python.org/library/functions.html#zip
it can also handle more than two lists, say n, and then creates n-tuples.
>>> zip([1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14])
[(1, 5, 9, 13), (2, 6, 10, 14)]
zip([1,2,3,4],[5,6,7])
--->[(1,5),(2,6),(3,7)]
args = [(1,5),(2,6),(3,7)]
zip(*args)
--->[1,2,3],[5,6,7]
The proper way is to use the zip function.
Alternativerly we can use list comprehensions and the built-in enumerate function
to achieve the same result.
>>> L1 = [1,2,3,4]
>>> L2 = [5,6,7]
>>> [(value, L2[i]) for i, value in enumerate(L1) if i < len(L2)]
[(1, 5), (2, 6), (3, 7)]
>>>
The drawback in the above example is that we don't always iterate over the list with the minimum length.
how to store elements in a tuple?
I did this:
for i in range (0, capacity):
for elements in self.table[i]:
# STORE THE ALL THE ELEMENTS IN THE TUPLE
tuples are immutable. You can create a tuple. But you cannot store elements to an already created tuple. To create (or convert) your list of elements to a tuple. Just tuple() it.
t = tuple([1,2,3])
In your case it is
t = tuple(self.table[:capacity])
Since you haven't told us - we can only guess what table looks like
If it is a list of lists for example, you can do this to get a tuple of tuples
>>> table =[[1,2,3],[4,5,6],[7,8,9]]
>>> tuple(map(tuple, table))
((1, 2, 3), (4, 5, 6), (7, 8, 9))
>>> capacity=2
>>> tuple(map(tuple, table[:capacity]))
((1, 2, 3), (4, 5, 6))
It's as easy as t = tuple(self.table[i])
I think this is what you want.
x = []
for i in range (0, capacity):
for elements in self.table[i]:
x.append(elements)
t = tuple(x)