I have following tuple:
vertices = ([0,0],[0,0],[0,0]);
And on each loop I want to append the following list:
[x, y]
How should I approach it?
You can't append a list to a tuple because tuples are "immutable" (they can't be changed). It is however easy to append a tuple to a list:
vertices = [(0, 0), (0, 0), (0, 0)]
for x in range(10):
vertices.append((x, y))
You can add tuples together to create a new, longer tuple, but that strongly goes against the purpose of tuples, and will slow down as the number of elements gets larger. Using a list in this case is preferred.
You can't modify a tuple. You'll either need to replace the tuple with a new one containing the additional vertex, or change it to a list. A list is simply a modifiable tuple.
vertices = [[0,0],[0,0],[0,0]]
for ...:
vertices.append([x, y])
You can concatenate two tuples:
>>> vertices = ([0,0],[0,0],[0,0])
>>> lst = [10, 20]
>>> vertices = vertices + tuple([lst])
>>> vertices
([0, 0], [0, 0], [0, 0], [10, 20])
You probably want a list, as mentioned above. But if you really need a tuple, you can create a new tuple by concatenating tuples:
vertices = ([0,0],[0,0],[0,0])
for x in (1, 2):
for y in (3, 4):
vertices += ([x,y],)
Alternatively, and for more efficiency, use a list while you're building the tuple and convert it at the end:
vertices = ([0,0],[0,0],[0,0])
#...
vlist = list(vertices)
for x in (1, 2):
for y in (3, 4):
vlist.append([x, y])
vertices = tuple(vlist)
At the end of either one, vertices is:
([0, 0], [0, 0], [0, 0], [1, 3], [1, 4], [2, 3], [2, 4])
Not sure I understand you, but if you want to append x,y to each vertex you can do something like :
vertices = ([0,0],[0,0],[0,0])
for v in vertices:
v[0] += x
v[1] += y
Related
I have a list of lists containing an index and two coordinates, [i,x,y] eg:
L=[[1,0,0][2,0,1][3,1,2]]
I want to check if L[i][1] is repeated (as is the case in the example for i=0 and i=1) and keep in the list only the list with the smallest i. In the example [2,0,1] would be removed and L would be:
L=[[1,0,0][3,1,2]]
Is there a simple way to do such a thing?
Keep a set of the x coordinates we've already seen, traverse the input list sorted by ascending i and build and output list adding only the sublists whose x we haven't seen yet:
L = [[1, 0, 0], [2, 0, 1], [3, 1, 2]]
ans = []
seen = set()
for sl in sorted(L):
if sl[1] not in seen:
ans.append(sl)
seen.add(sl[1])
L = ans
It works as required:
L
=> [[1, 0, 0], [3, 1, 2]]
There are probably better solution but you can do with:
i1_list=[]
result_list=[]
for i in L:
if not i[1] in i1_list:
result_list.append(i)
i1_list.append(i[1])
print(result_list)
For example:
alist=[['a','b'],[1,2]]
and the combination
('a',1)
Is there a way to get the index of this combination i.e. (0,0) because both are at the 0-th position in their respective list or a matrix like
[[1,1],[0,0]]
where the 1s indicate the position get selected to form the combination?
Well you can just create the indices as ruaridhw pointed out. You can do it like so:
from itertools import product
alist = [['a','b'],[1,2]]
print [a for a in product(*alist)]
print [list(a) for a in product(*[range(len(x)) for x in alist])]
Output:
[('a', 1), ('a', 2), ('b', 1), ('b', 2)]
[[0, 0], [0, 1], [1, 0], [1, 1]]
Since each element of given combination c is to be found in the corresponding row of alist, the following returns the tuple of their indices:
alist = [['a','b'],[1,2]]
c = ('a',1)
ix = tuple(row.index(elem) for row, elem in zip(alist, c))
Here ix becomes (0, 0)
I have list in this style:
[ [x,y,z] , [x1,y1,z1] , [...]].
My problem is that I want to make a new list with somehow sorted values. In a first step I want to make a list where for all the same x and y I have the corresponding z values. Here is a example:
raw data:
[[1,2,5],[1,2,6],[1,2,7],[2,2,10],[2,2,11]]
processed data:
[[1,2 [5,6,7]],[2,2[10,11]]
In the final step I would like to have list like that:
[[x values], [y values], [z minimum values], [z length]]
[[1,2],[2,2],[5,10],[3,2]]
First I tried to make a list with all possible combinations of x and y (its not infinite in my data) but then I thought that just comparing the consecutive values would be easier, but I didnt figure it out.
If you are starting out, it would be useful to break the problem into smaller problems and tackle it bit by bit.
For the first step, the easiest approach might be to first collect the information using a dictionary.
You go through all triplets in the original list and create a dictionary where each key is a distinct (x, y) pair. Values would be z values from the list.
import collections
l = [[1,2,5],[1,2,6],[1,2,7],[2,2,10],[2,2,11]]
mapping = collections.defaultdict(list)
for x, y, z in l:
mapping[(x, y)].append(z)
# >> defaultdict(<type 'list'>, {(1, 2): [5, 6, 7], (2, 2): [10, 11]})
We are using a defaultdict, with a list constructor, so that we don't have to manually check if an items already exists in the list.
Now that we have a dictionary, it is easy to build the first list. We just have to go through all keys and values and create a proper list format.
intermediate_list = [[x, y, zs] for (x, y), zs in mapping.iteritems()]
# >> [[1, 2, [5, 6, 7]], [2, 2, [10, 11]]]
In the third step we can again utilize our dictionary. First entries in the list will be all keys from the dictionary and then we need to keep adding minimum and maximum values.
final_list = []
minimums = []
lengths = []
for (x, y), zs in mapping.iteritems():
final_list.append([x, y])
minimums.append(min(zs))
lengths.append(len(zs))
final_list.append(minimums)
final_list.append(lengths)
# >> [[1, 2], [2, 2], [5, 10], [3, 2]]
I am not able to figure out what is happening here. Appending reference to range function is kind of creating a recursive list at index 3.
>>> x = range(3)
[0, 1, 2]
>>> x.append(x)
[0, 1, 2, [...]]
>>> x[3][3][3][3][0] = 5
[5, 1, 2, [...]]
Whereas, when I try this:
>>> x = range(3)
[0, 1, 2]
>>> x.append(range(3))
[0, 1, 2, [0, 1, 2]]
I can easily deduce the reason for the second case but not able to understand what appending reference to range function is doing to the list appended.
In python2, ranges are lists.
lists, and most of the things in python are objects with identities.
li = [0,1]
li[1] = li # [0, [...]]
# ^----v
id(li) # 2146307756
id(li[1]) # 2146307756
Since you're putting the list inside itself, you're creating a recursive data structure.
First this is strange, and you probably should not use this in practice. The issue is not specific to range function and has to do with references. When you call x.append(x), you essentially say that x[-1] is x. So when you modify x[0], you also modify x[-1][0], x[-1][-1][0] etc.
To see that this is not range specific, you could use copy.copy:
from copy import copy
x = range(1)
x.append(x) # here x[1] is reference to x itself (same object)
print(x[0], x[1][0], x[1][1][0])
x[0] = 1
print(x[0], x[1][0], x[1][1][0]) # all values change
#
x = range(1)
x.append(copy(x)) # x[1] is a copy of x at previous state (new object)
print(x[0], x[1][0]) # cannot call x[1][1][0] -> x[1][1] is an int
x[0] = 1
print(x[0], x[1][0]) # only the first value changes
Output:
(0, 0, 0)
(1, 1, 1)
(0, 0)
(1, 0)
I'm trying to generate a list of all possible 1-dimensional positions for an arbitrary number of identical objects. I want it formatted so each coordinate is the distance from the previous object, so for 3 objects (0,5,2) would mean one object is at position 0, another is at position 5 and another is at position 7.
So the main restraint is that the sum of the coordinates is <=D. Nested for loops works well for this. For example, with 3 objects with maximum coordinate D:
def positions(D):
output=[]
for i in range(D+1):
for j in range(D+1-i):
for k in range(D+1-i-j):
output.append((i,j,k))
return(output)
What's the best way to extend this to an arbitrary number of objects? I can't find a good way without explicitly writing a specific number of for loops.
I think you can combine itertools.combinations, which will give you the locations, with taking the difference, which should give you your "distance from the previous object" behaviour. For example, using
def diff(loc):
return [y-x for x,y in zip((0,) + loc, loc)]
we have
In [114]: list(itertools.combinations(range(4), 3))
Out[114]: [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
for the possible positions, and then
In [115]: [diff(x) for x in itertools.combinations(range(4), 3)]
Out[115]: [[0, 1, 1], [0, 1, 2], [0, 2, 1], [1, 1, 1]]
for your relative-distance version.