I have a list of lists in python, where in my case the lists are coordinates. I want to append new coordinates to this list, but only if the coordinate does not exist yet. This is easily doable in the following manner.
List = [coord1,coord2,...,coordn]
coord = [x,y,z]
if not coord in List: List.append(coord)
The problem is that these coordinates are generated with all kinds of goniometric functions, so they are floats, and the following minimal example can arise:
List =[[0,0],[1,0]]
coords = [0.99999999999,0.000000000001]
I do not want to add the new coordinate, so I was wondering if there is some kind of easy way to check if there is a simple function func, which would do something like the following:
List =[[0,0],[1,0]]
coord = [0.99999999999,0.000000000001]
tol = 1e-10
func(coord,List,tol) = True
i.e. func returns True if there is a existing coordinate c in List, such that ||c-coord||<tol. One of the constraints is that List remains a list, so it is preferred if it doesn't need to be converted to a numpy array, but the use of numpy in general is possible, and necessary I guess.
this is a common problem, which can be solved by rounding the float value:
coord = [0.99999999999,0.000000000001]
rounded_coord = [ '%.2f' % elem for elem in coord ]
this should return the list with the rounded float values, but they will be of type String.
to work with the data, it is probably better to convert the strings to floats again by changing the code:
rounded_coord = [ float('%.2f' % elem) for elem in coord ]
Related
I only want to know what is the meaning of [x] in a function (In general, not about the code that I will show), which I always think as a list but found nothing about it.
I will show two codes that I have seen using it, the first one is using PyTorch Library (Convolution):
Short one:
x.size()[0]
Long one:
def forward(self, x):
conv_out = self.conv(x).view(x.size()[0], -1)
return self.fc(conv_out)
The second one is using GYM library for RL, but also part of the code above:
Short one:
assert env.unwrapped.get_action_meanings()[1] == 'FIRE'
Long one:
def __init__(self, env=None):
"""For environments where the user need to press FIRE for the game to start."""
super(FireResetEnv, self).__init__(env)
assert env.unwrapped.get_action_meanings()[1] == 'FIRE'
assert len(env.unwrapped.get_action_meanings()) >= 3
I don't want to know why they are using the function()[x], I only want to know what is the [x] in general.
Thank for the answer.
[] is the indexing operator in Python.
If you have a list or tuple l, l[n] means the nth element of it.
If you have a dictionary d, d[x] means the element whose key is x.
If you have a string s, s[n]means then`th character in the string.
Some other datatypes define their own indexing functions, but they generally implement the same idea, possibly extending it (Numpy arrays allow you to use a tuple to perform multi-dimensional indexing and slicing).
If you put [x] after a function call, it performs the indexing on whatever the function returns.
y = function()[x]
is equivalent to
temp = function()
y = temp[x]
The [x] that comes after the several types of input you describe is simply an index reference. It can apply to lists, tuples or dicts, depending on how you use them. For example:
z = np.zeros((2, 3)) #Creates a numpy array of zeros with size (2, 3)
print(z.size()) #Outputs (2, 3)
print(z.size()[0]) #outputs the 0th index of the tuple
print(z.size()[2]) #Returns index error as it is out of range
The same applies for lists and dicts but comes with varied problems. Most of the time, for functions, this is used only if you know what is the format of the return value and you only need a part of it.
Hope this helps.
I want to create dynamic arrays inside a dynamic array because I dont know how many lists it will take to get the actual result. So using python 2.x when I write
Arrays = [[]]
does this mean that there is only one dynamic array inside an array or it can mean to be more than one when call for it in for loop like arrays[i]?
If it's not the case do you know a different method?
You can just define
Arrays = []
It is enough to hold your dynamic array.
AnotherArray1 = []
AnotherArray2 = []
Arrays.append(AnotherArray1)
Arrays.append(AnotherArray2)
print Arrays
Hope this solves your problem!
Consider using
Arrays = []
and later, when you are assigning your results use
Arrays.append([result])
This is assuming that your result comes in slices, but not as an array. No matter your actual return value layout, a variation of the above .append() should do the trick, as it allows you to dynamically extend your array. If your result comes as an array, it would simply be
Arrays.append(result)
and so on
If your array is going to be sparse, that is a lot of empty elements, you can consider to have a dict with coordinates as keys instead of nested lists:
grid = {}
grid[(x, y)] = value
print(grid)
output: {(x, y): value}
I am creating a list in python in the following way:
new_points = [None] * 25
for point in points:
new_points[point.id] = point
I am wondering if this can be achieved by Python one-line list comprehension. Please note that each point has a unique id. Hence two points can never have same ids.
This sounds like you want to sort the list rather than use a comprehension.
new_points = sorted(points, key=lambda x:x.id)
The sorted function takes an iterable and a key function and returns a list. In this case the key function only needs to get the id.
I don't know of any way to populate random locations in a list with a one-liner. But if all you want is to be able to find a point by its id, you could use a dict in stead of a list:
new_points = {p.id: p for p in points}
I have a list of coordinates like:
[44.64,-123.11;38.91,-121.99;40.35,-122.28;43.21,-123.36;41.77,-122.58;37.77,-122.42]
I need to sort this list. Any suggestions ?
EDIT:
Sorry for not sharing the expected output:
It should be [44.64,-123.11;43.21,-123.36;41.77,-122.58;40.35,-122.28;38.91,-121.99;37.77,-122.42]
li = [44.64,-123.11;38.91,-121.99;40.35,-122.28;43.21,-123.36;41.77,-122.58;37.77,-122.42]
Your "list" looks more like a string, with ";" and "," to separate 2D points and their values. I imagine that you want a list of tuples, that represent the x and y coordinates? So first you need to split your string into a list
li = li.split(';')
Now you have a list of strings, that you need to split into pairs of float values. You can do that with two list comprehensions
li = [(float(a.split(',')[0]), float(a.split(',')[1])) for a in li]
Now you have a list of coordinates that you could sort in some way. Maybe smallest x first or something. Use Python's sorted build-in function to do that, e.g.
sorted_li = sorted(li, key=lambda x: x[0])
The docs are here, read them.
https://docs.python.org/3.6/library/functions.html#sorted
Raised by this question's comments (I can see that this is irrelevant), I am now aware that using dictionaries for data that needs to be queried/accessed regularly is not good, speedwise.
I have a situation of something like this:
someDict = {}
someDict[(-2, -2)] = something
somedict[(3, -10)] = something else
I am storing keys of coordinates to objects that act as arrays of tiles in a game. These are going to be negative at some point, so I can't use a list or some kind of sparse array (I think that's the term?).
Can I either:
Speed up dictionary lookups, so this would not be an issue
Find some kind of container that will support sparse, negative indices?
I would use a list, but then the querying would go from O(log n) to O(n) to find the area at (x, y). (I think my timings are off here too).
Python dictionaries are very very fast, and using a tuple of integers is not going to be a problem. However your use case seems that sometimes you need to do a single-coordinate check and doing that traversing all the dict is of course slow.
Instead of doing a linear search you can however speed up the data structure for the access you need using three dictionaries:
class Grid(object):
def __init__(self):
self.data = {} # (i, j) -> data
self.cols = {} # i -> set of j
self.rows = {} # j -> set of i
def __getitem__(self, ij):
return self.data[ij]
def __setitem__(self, ij, value):
i, j = ij
self.data[ij] = value
try:
self.cols[i].add(j)
except KeyError:
self.cols[i] = set([j])
try:
self.rows[j].add(i)
except KeyError:
self.rows[j] = add([i])
def getRow(self, i):
return [(i, j, data[(i, j)])
for j in self.cols.get(i, [])]
def getCol(self, j):
return [(i, j, data[(i, j)])
for i in self.rows.get(j, [])]
Note that there are many other possible data structures depending on exactly what you are trying to do, how frequent is reading, how frequent is updating, if you query by rectangles, if you look for nearest non-empty cell and so on.
To start off with
Speed up dictionary lookups, so this would not be an issue
Dictionary lookups are pretty fast O(1), but (from your other question) you're not relying on the hash-table lookup of the dictionary, your relying on a linear search of the dictionary's keys.
Find some kind of container that will support sparse, negative indices?
This isn't indexing into the dictionary. A tuple is an immutable object, and you are hashing the tuple as a whole. The dictionary really has no idea of the contents of the keys, just their hash.
I'm going to suggest, as others did, that you restructure your data.
For example, you could create objects that encapsulate the data you need, and arrange them in a binary tree for O(n lg n) searches. You can even go so far as to wrap the entire thing in a class that will give you the nice if foo in Bar: syntax your looking for.
You probably need a couple coordinated structures to accomplish what you want. Here's a simplified example using dicts and sets (tweaking user 6502's suggestion a bit).
# this will be your dict that holds all the data
matrix = {}
# and each of these will be a dict of sets, pointing to coordinates
cols = {}
rows = {}
def add_data(coord, data)
matrix[coord] = data
try:
cols[coord[0]].add(coord)
except KeyError:
# wrap coords in a list to prevent set() from iterating over it
cols[coord[0]] = set([coord])
try:
rows[coord[1]].add(coord)
except KeyError:
rows[coord[1]] = set([coord])
# now you can find all coordinates from a row or column quickly
>>> add_data((2, 7), "foo4")
>>> add_data((2, 5), "foo3")
>>> 2 in cols
True
>>> 5 in rows
True
>>> [matrix[coord] for coord in cols[2]]
['foo4', 'foo3']
Now just wrap that in a class or a module, and you'll be off, and as always, if it's not fast enough profile and test before you guess.
Dictionary lookups are very fast. Searching for part of the key (e.g. all tiles in row x) is what's not fast. You could use a dict of dicts. Rather than a single dict indexed by a 2-tuple, use nested dicts like this:
somedict = {0: {}, 1:{}}
somedict[0][-5] = "thingy"
somedict[1][4] = "bing"
Then if you want all the tiles in a given "row" it's just somedict[0].
You will need some logic to add the secondary dictionaries where necessary and so on. Hint: check out getitem() and setdefault() on the standard dict type, or possibly the collections.defaultdict type.
This approach gives you quick access to all tiles in a given row. It's still slow-ish if you want all the tiles in a given column (though at least you won't need to look through every single cell, just every row). However, if needed, you could get around that by having two dicts of dicts (one in column, row order and the other in row, column order). Updating then becomes twice as much work, which may not matter for a game where most of the tiles are static, but access is very easy in either direction.
If you only need to store numbers and most of your cells will be 0, check out scipy's sparse matrix classes.
One alternative would be to simply shift the index so it's positive.
E.g. if your indices are contiguous like this:
...
-2 -> a
-1 -> c
0 -> d
1 -> e
2 -> f
...
Just do something like LookupArray[Index + MinimumIndex], where MinimumIndex is the absolute value of the smallest index you would use.
That way, if your minimum was say, -50, it would map to 0. -20 would map to 30, and so forth.
Edit:
An alternative would be to use a trick with how you use the indices. Define the following key function
Key(n) = 2 * n (n >= 0)
Key(n) = -2 * n - 1. (n < 0)
This maps all positive keys to the positive even indices, and all negative elements to the positive odd indices. This may not be practical though, since if you add 100 negative keys, you'd have to expand your array by 200.
One other thing to note: If you plan on doing look ups and the number of keys is constant (or very slowly changing), stick with an array. Otherwise, dictionaries aren't bad at all.
Use multi-dimensional lists -- usually implemented as nested objects. You can easily make this handle negative indices with a little arithmetic. It might use a more memory than a dictionary since something has to be put in every possible slot (usually None for empty ones), but access will be done via simple indexing lookup rather than hashing as it would with a dictionary.