Changing elements of a list of lists [duplicate] - python

This question already has answers here:
How to add 1 to every element of a matrix / nested list in Python?
(4 answers)
Closed 1 year ago.
I need to add 0.05 to elements of coords array. But nothing happens.
Can you advise me where is the mistake? (I thought this would be easy but no)
coords = [[0.1,0.1,0.1],
[0.2,0.2,0.2],
[0.3,0.3,0.3]]
for i in coords:
for j in i:
j = j+0.05
print(coords)

Your solution doesn't actually modify the elements in the list by iterating over j. You could try a double list comprehension like this:
coords[:] = [j+0.05 for i in coords for j in i]
This has the advantage of editing the original object without creating a new instance of a list.

You current way will not store the results, as you did not provide a list to hold the results. I can show you two more straightforward examples:
a = [1,2,3,4]
for number in a:
number = number + 1
# check results
# nothing happens
print(a)
But if you do:
# you will get results
b = [number + 1 for number in a]
print(b)
The only difference is that you need to provide a list to hold the data.

Try this:
coords = [[0.1,0.1,0.1],
[0.2,0.2,0.2],
[0.3,0.3,0.3]]
for i in range(len(coords)):
for j in range(len(coords[i])):
coords[i][j] += .05
print(coords)

You can use lst comprehension
coords = [[0.1,0.1,0.1],
[0.2,0.2,0.2],
[0.3,0.3,0.3]]
newCoords = [[num+0.05 for num in lst] for lst in coords ]
print(newCoords)

Related

How can I create lists within a loop from a list of strings with each string becoming a separate unique list I can now access in Python

I want to generate 25 unique lists from a starting list of values within a loop, how can I turn a string list elements into lists in such a way that I can increment every loop and save the new list so that as an end result I have 25 separate lists named list1,list2...list25 that I can access for further use?
In my loop, I have written stringList[count] where I need to create the list from the string list, I know it's incorrect, I just put it there so that it's easy to understand where and what I'm looking for. For example, it should create list1 and copy currentList values to it there on the first loop, then list 2 and so on.
stringList = ['list1','list2','list3','list4','list5','list6','list7','list8','list9',
'list10','list11','list12','list13','list14','list15','list16','list17','list18','list19',
'list20','list21','list22','list23','list24','list25']
startingList = [0,1,0,1,0,1]
currentList = []
currentList2 = []
count = 0
for x in range(5):
if x == 0:
currentList = list(startingList)
#code that modifies currentList into a new unique list
stringList[count] = list(currentList)
count += 1
for y in range(5):
if y == 0:
currentList2 = list(currentList)
#code that modifies currentlist2 into a new unique list
stringList[count] = list(currentList2)
count += 1
Edit : Would something like this work? Never mind, this won't work. I need to turn the string elements of stringList into lists 1 at a time per loop, not all at once.
S = "".join([n +'= [];' for n in stringList])
exec(S)
You could do it with exec if you really needed to, but it generally is not that useful. I'd suggest you store all the lists in a dictionary instead. Here is a simple example (let's just concentrate on storing the lists and you can figure out the rest; btw the code in your question doesn't run - you have count += 1 in both loops which produces an index out of range error). For the purpose of this example we will create 5 lists, holding their index three times inside of them.
exec:
>>>for ind in range(5):
>>> exec("list{} = [{}]*3".format(ind, ind))
#we created the name as a string but now we have to access it as a variable
#it's a bit clumsy
>>>list2
Out[2]: [2, 2, 2]
dictionary - read more here:
>>>lists = {}
>>>for ind in range(5):
>>> lists["list{}".format(ind)] = [ind] * 3
#arguably neater
>>>lists["list2"]
Out[6]: [2, 2, 2]

How to calculate numbers in a list [duplicate]

This question already has answers here:
Python: Finding differences between elements of a list
(12 answers)
Difference between consecutive elements in list [duplicate]
(3 answers)
Closed 4 years ago.
here is my code.
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(len(A)):
c = A[i]-A[i-1]
B.append(c)
print(c)
I want to get the differences between two continuous numbers in this list, eg,(85.25496701-86.14803712). So in the results, I should have eight numbers as results.
But the results I get are:
-0.9337014900000042
-0.8930701099999965
1.2483756999999969
-0.4766759099999973
0.5878891400000015
0.2898961899999932
-0.24925897999999336
0.4459744699999959
-0.019429009999996083
I don't need -0.9337014900000042 since it comes from the first number subtract the last number in the list. What should I do the fix it? Thanks
That's the strength and the weakness of python: index -1 is always valid when the list isn't empty, which can lead to programs not crashing but not doing what you want.
For those operations, it's better to use zip to interleave the list with a sliced version of itself without the first number:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
diffs = [ac-ap for ac,ap in zip(A[1:],A)]
or with itertools.islice to avoid creating a new list to iterate on it:
import itertools
diffs = [ac-ap for ac,ap in zip(itertools.islice(A,1,None),A)]
result (8 values):
[-0.8930701099999965, 1.2483756999999969, -0.4766759099999973, 0.5878891400000015, 0.2898961899999932, -0.24925897999999336, 0.4459744699999959, -0.019429009999996083]
It's possible to do this in base Python, but you might like the semantic clarity of Pandas:
import pandas as pd
pd.Series(A).diff().values[1:]
array([-0.89307011, 1.2483757 , -0.47667591, 0.58788914, 0.28989619,
-0.24925898, 0.44597447, -0.01942901])
You can just do:
B = [x-y for x, y in zip(A[1:], A)]
print(B) # -> [-0.8930701099999965, 1.2483756999999969, -0.4766759099999973, 0.5878891400000015, 0.2898961899999932, -0.24925897999999336, 0.4459744699999959, -0.019429009999996083]
You need to make sure you star from a correct index. In your current code, in the first iteration of the loop you will be computing A[0] - A[-1]. Hence, you need to start i from 1 to ensure in the first iteration you compute the value of A[1] - A[0]. The corrected version of your code is here:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(1, len(A)):
c = A[i]-A[i-1]
B.append(c)
print(c)
I think the problem is that the loop subtracts the first element to the last because the loop starts at index 0 and subtracts it from index -1 (python takes -1 as the last index of a list). A better solution imo would be:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594,
86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(len(A)-1):
c = -(A[i]-A[i+1])
B.append(c)
print(c)
The easiest would be:
result = [x-y for x,y in zip(A[1:], A[:-1])]

Separate elements of array into two arrays [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 5 years ago.
I did one simple code to separate elements of an array into two new arrays : one with odd numbers and other with even numbers. So I did this:
V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V:
if x%2==0:
vp.append(x)
V.remove(x)
else:
vi.append(x)
V.remove(x)
print (V)
print (vp)
print (vi) # sorry for the bad identation first time sharing code here
and this code give me this result:
[2,4,6]
[]
[1,3,5]
How is it happen? How am I fix this?
You shouldn't remove item while traversing an array:
V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V:
if x%2==0:
vp.append(x)
else:
vi.append(x)
Modifying a list mid-iteration causes misbehavior (you effectively skip input elements). Don't remove from V as you go (which for long V would be expensive, each remove is O(n) making total work O(n**2)), just leave V unmodified. If necessary, clear V when you finish (a single O(n) operation), e.g. after the loop:
del V[:]
When you remove items from a list, the list gets shorter. So when you're looping over a list in a forward direction, removing items will cause the the iterator to skip forward.
To mitigate this, you can loop backwards over a list and safely remove items, since you're removing them from the end.
V = [1,2,3,4,5,6]
vp = []
vi = []
# reverse the list before iterating
for x in reversed(V):
if x % 2 == 0:
vp.append(x)
V.remove(x)
else:
vi.append(x)
V.remove(x)
Other answers that identified the problem and the fix, but here is a different way to do it using list comprehensions.
numbers = [1,2,3,4,5,6]
even = [e for e in numbers if e % 2 == 0]
odd = [e for e in numbers if e % 2 == 1]
A more concise way to make a new odd and even list from the original is to use comprehensions:
v = [1,2,3,4,5,6]
even = [number for number in v if number % 2 == 0]
odd = [number for number in v if number % 2 != 0]
Don't remove items from a list over which you are iterating. Use a copy:
V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V[:]:
if x%2==0:
vp.append(x)
V.remove(x)
else:
vi.append(x)
V.remove(x)
print (V)
print (vp)
print (vi)
# []
# [2, 4, 6]
# [1, 3, 5]

Obtaining the first and second "column's" from a pair of lists

I have many pairs of lists of variable lengths (5,4,6 pairs etc..) inside a single big list, lets call it LIST. Here are two lists among the many inside the big LIST as an example:
[(38.621833, -10.825707),
(38.572191, -10.84311), -----> LIST[0]
(38.580202, -10.860877),
(38.610917, -10.85217),
(38.631526, -10.839338)]
[(38.28152, -10.744559),
(38.246368, -10.744552), -----> LIST[1]
(38.246358, -10.779088),
(38.281515, -10.779096)]
I need to create two seperate variables lets say, of which one variable will have the first "column" (i.e. LIST[0][0][0], LIST[0][1][0] AND SO ON) of all the pairs of the lists(i.e. 38.621833, 38.572191 etc) and the second variable will have the second "column" (i.e. LIST[0][0][1], LIST[0][1][1] AND SO ON) of all the pairs of the lists.
So finally I will have two variables (say x,y) that will contain all the values of the first and second "columns" of all the lists in the LIST.
The problem I face is that all these lists are not of the same length!!
I tried
x = []
y = []
for i in range(len(LIST)):
x.append(LIST[i][0][0]) #append all the values of the first numbers
y.append(LIST[i][1][1]) #append all the values of the second numbers
What I expect:
x = (38.621833,38.572191,38.580202,38.610917,38.631526,38.28152,38.246368,38.246358,38.281515)
y = (-10.825707,-10.84311,-10.860877,-10.85217,-10.839338,-10.744559,-10.744552,-10.779088,-10.779096)
But here because of the variable pairs, my loop stops abrubptly in between.
I know I need to also change the LIST[i][j][0] here, and j changes with each list. But because of the different pairs, I don't know how to go about.
How do I go about doing this?
I would use two simple for loops (it's also generic for LIST being longer than 2):
x=[]
y=[]
for i in range(len(LIST)):
for j in LIST[i]:
x.append(j[0])
y.append(j[1])
You should transpose the sublists and use itertool.chain to create a single list:
from itertools import chain
zipped = [zip(*x) for x in l]
x, y = chain.from_iterable(ele[0] for ele in zipped),chain.from_iterable(ele[1] for ele in zipped)
print(list(x),list(y))
[38.621833, 38.572191, 38.580202, 38.610917, 38.631526, 38.28152, 38.246368, 38.246358, 38.281515] [-10.825707, -10.84311, -10.860877, -10.85217, -10.839338, -10.744559, -10.744552, -10.779088, -10.779096]
for ele1,ele2 in zip(x,y):
print(ele1,ele2)
38.621833 -10.825707
38.572191 -10.84311
38.580202 -10.860877
38.610917 -10.85217
38.631526 -10.839338
38.28152 -10.744559
38.246368 -10.744552
38.246358 -10.779088
38.281515 -10.779096
Here you go. tuple as requested.
my = [(38.621833, -10.825707),(38.572191, -10.84311),(38.580202, -10.860877),(38.610917, -10.85217),(38.631526, -10.839338)]
my1 = [(38.28152, -10.744559),(38.246368, -10.744552),(38.246358, -10.779088),(38.281515, -10.779096)]
l1 = map(tuple,zip(*my))[0]
l2 = map(tuple,zip(*my))[1]
print l1,l2
Output:
(38.621833, 38.572191, 38.580202, 38.610917, 38.631526)(-10.825707, -10.84311, -10.860877, -10.85217, -10.839338)
Use map function with zip and * stuple operator.
l = [(38.621833, -10.825707),
(38.572191, -10.84311),
(38.580202, -10.860877),
(38.610917, -10.85217),
(38.631526, -10.839338)]
x= map(list, zip(*l))[0]
y = map(list, zip(*l))[1]
print 'x = {},\n y = {}' .format(x,y)
x = [38.621833, 38.572191, 38.580202, 38.610917, 38.631526],
y = [-10.825707, -10.84311, -10.860877, -10.85217, -10.839338]
or if you don't want to store it in variables then d0n't use indexing in above solution,
map(list, zip(*l)) # will give you a nested list
Your LIST extends out of 2 lists.
With
for i in range(len(LIST)):
you run exactly 2 times through your loop.
If you want to solve your problem with for-loops your need to nest them:
#declare x, y as lists
x = []
y = []
for i_list in LIST:
#outer for-loop runs 2 times - one for each list appended to LIST.
#1st run: i_list becomes LIST[0]
#2nd run: i_list becomes LIST[1]
for touple in i_list:
#inner for-loop runs as often as the number of tuple appended to i_list
#touple becomes the content of i_list[#run]
x.append(touple[0]) #adds x-value to x
y.append(touple[1]) #adds y-value to y
If you prefer working with indexes use:
for i in range(len(LIST)):
for j in range(len(LIST[i])):
x.append(LIST[i][j][0])
y.append(LIST[i][j][1]])
NOT working with indexes for appending x- or y-values is much easier to write (saves complex thoughts about the List-Structure and correct using of indexes) and is much more comprehensible for extern people reading your code.

Python creating variables with names from range [duplicate]

This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 8 years ago.
I want to use some code similar to what follows that actually works:
P = 20
n = 1
for x in range(1, P+1):
Ax = n #Hoping that you can name the variable from the current element in the range
n = n+1
I want to make varibles A1, A2, A3....A20 they would have the values 1, 2, 3...20 in this example...
Is this possible at all, and what coding does it require?
Cheers
You don't actually want to do this. Instead, you want something like this:
P = 20
n = 1
A = [] # Or `A = list()`
for x in range(1, P+1):
A.append(n)
n += 1
Then, instead of A0, you do A[0] and instead of A5 you do A[5].
Here is the Python 3.x list documentation (I presume you are using Python 3.x due to using range rather than xrange.
Also, as I understand it, your code could just be this:
P = 20
A = []
for x in range(1, P+1):
A.append(x)
Or this:
P = 20
A = [i for i in range(1, P+1)]
(See the documentation for list comprehensions, a very useful feature of Python.)
Or even:
P = 20
A = list(range(1, P+1))
Do not try to dynamically name variables. That way madness lies.
Instead, leverage python's data structures to do what you want. In most cases, people really want to be using a dict or a list.
a = {}
for x in range(1,21):
a[x] = x**2
b = []
for x in range(1,21):
b.append(x**2)
You will get a feel for when you want to use one over the other. For example, in the above if I needed to quickly look up the square of a given integer, I would use a dict. If I instead just needed to do something to the collection of squares between 1 and 20, that's when I use a list.
Trivial example, but this scales up as far as you need it to. Any hashable data type can be a key in a dictionary, so you're no longer restricted from naming your variables with clunky letters and numbers - any object will do!
I almost agree with all the answers and comments you got so far:
99.99% of the times, you don't want to do this. It's dangerous, ugly and bad.
However there is a way to do it, using exec:
P = 20
n = 1
for x in range(1, P+1):
exec("A{} = n".format(x))
n = n+1
Again, you probably shouldn't use this.

Categories

Resources