Python creating variables with names from range [duplicate] - python

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.

Related

Changing elements of a list of lists [duplicate]

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)

How to incrementally assign variable names using numbers inside a for loop in python?

I have a simple code where I want to update the variable names as follows:
n = 5
for i in range(0, n):
train_fold_[i], val_fold_[i] = result[i][0],result[i][1]
I want the above code to generate a total of 10 variables with names train_fold_0, val_fold_0, train_fold_1, val_fold_1,......, train_fold_4, val_fold_4.
However, when I run this code, it is only generating 2 variables as follows: train_fold_i, val_fold_i.
I know this is extremely simple, but can someone please help me out with this as I'm relatively new to python.
You could use exec
n = 5
for i in range(0, n):
value1, value2 = i, i+1
exec(f'train_fold_{i}, val_fold_{i} = {value1}, {value2}')
then
print(train_fold_3, val_fold_3)
>>> 3 4

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

Troubles with matrix in python

Yesterday, I was trying to solve a problem with python, and I encountered something really odd:
# create matrix
for i in range(N):
tmp.append(0)
for i in range(N):
marker.append(tmp)
# create sum of 2 first cards
for i in range(N) :
for j in range(N):
if i != j and marker[i][j] == 0:
comCard.append(deck[i]+deck[j])
taken[deck[i]+deck[j]] = [i,j]
marker[i][j] = 1
marker[j][i] = 1
The idea is that I want to calculate all the possible sums of each pair of cards in the deck (these cards need to be different), so I think that with a marker, I can avoid calculating the same 2 cards again. for example: deck[1]+deck[2] and deck[2]+deck[1]. But these lines didn't work as they were supposed to do:
marker[i][j] = 1
marker[j][i] = 1
I can recommend another way using standard python modules:
# suppose this is a deck - list of cards (I don't know how to mark them :)
>>> deck = ['Ax', 'Dy', '8p', '6a']
>>> from itertools import combinations
# here's a list of all possible combinations of 2 different cards
>>> list(combinations(deck, 2)))
[('Ax', 'Dy'), ('Ax', '8p'), ('Ax', '6a'), ('Dy', '8p'), ('Dy', '6a'), ('8p', '6a')]
You may work with this list: check some combinations and so on.
I recommend to pay attention to library itertools - it's really awesome for such type computations!
You're using the same instance of tmp, only shallow-copied. That's why it doesn't work. You need a new copy of each line to add in your matrix.
This can be done with:
marker.append(list(tmp))
Also, you may benefit from using True and False instead of 0 and 1 someday. So the initialisation of your matrix could rahter look like this:
tmp = list()
marker = list()
for i in range(N):
tmp.append(False)
for j in range(N):
marker.append(list(tmp))
This way, when you try marker[i][j] = True, only the index (i, j) will be affected.
That being said, Eugene Lisitsky's answer gives you a far more adapted tool for this kind of matter (permutation listing).

Updating a list in a loop in python without using the append function.

Hi there suppose I have;
a = np.array([1.,2.])
b = np.array([3.,4.])
r = []
...
for i in range(10)
b*i
r[i] = ((a[0]+b[0]) - (a[1] - b[1]))
...
i = i+1
The code is meant to take arrays a and b and perform addition and subtraction on elements from them, and place them into what I think should be a list, which in this case I've called r. (i.e so r[0] = 0, r[1] = 6 etc.)
I know this does not work, but I don't know why can someone tell me what I should define 'r' to be?
I'd rather avoid using something like;
r.append(...)
The end goal is to plot r vs i , should I therefore construct both lists and then plot them against eachother, or should I include it in the loop somehow.
Thanks in advance!
Use list comprehensions, as an example, I'm going to rewrite your whole for loop and r = [] into this:
r = [((a[0]+(b*i)[0]) - (a[1] - (b*i)[1])) for i in range(1,10)]
This does the same, more readable, much more faster.

Categories

Resources