This question already has answers here:
using locals() inside dictionary comprehension
(2 answers)
Closed last year.
Inside a script I have conditions to created variables with names of files. At the end of the script I want to know which variables were created. I use in locals() function to check it. If I do if with a simple list building it works fine, but with list comprehension I don't get the results. Why?
To be clear, I don't need suggestions to bypass the problem (I can just use the simple list building), just an explanation to the behaviour.
In my example file_08 and file_14 variables were created, but file_15 wasn't.
all_files = []
for file in ['file_08', 'file_14', 'file_15']:
if file in locals():
all_files.append(file)
print(all_files)
['file_08', 'file_14']
Works, but:
print([file for file in ['file_08', 'file_14', 'file_15'] if file in locals()])
[]
Doesn't work
The locals() function returns a dictionary containing the variables defined in the local namespace. Unless you have defined variables with the names 'file_88', 'file_14', and 'file_15' within the executable name space, you will get an empty list. You can verify this by printing the contents of locals() and see what you get back.
Related
This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 2 years ago.
How to assign variable names programmatically in python?
I have a lot of objects and their names are not predefined. Currently I am reading in from a file which has names in it and I’m reading in them into a list. But from this list how do I assign the names to the variables so that variables are easy to remember and work with. I cannot hard code because :
a. I don’t want them to be fixed
b. I have a lot of names so it is not feasible to type in. (Even copy paste every name)
Use dictionaries. (And assign its keys programmatically!)
You can assign the variables names which you’ve already read into the list and then have their values read. I’m still not clear about how you want your values but assuming you have them in a list too as you have your variable names, then just zip both lists as dict:
data = dict(zip(names, values))
Now you can access each variable by its name as follows:
data['name']
This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 2 years ago.
In a different question I tried to use an enumerate and for element to create a pandas dataframe using the element as the name. It turns out the problem is more general. Is there anyway to set a variable value using something other than a plain string? In Bash this is done with the Read command, which takes the previous output into a subshell and assigns it to a variable name (I'll post my question on that below).
Any way to do this in Python? i.e., something simple like:
list1[0] = pd.dataframe(data), where list1[0] is a string. Or similarly using a dict key where the value is a dataframe:
for i in dict1: i = dict1[key] or for i in dict1: function(i) = dict1[key]?
The latter doesn't work using str() or any function because the error complains "SyntaxError: can't assign to function call", but maybe something similar?
Python: How can I use an enumerate element as a string?
https://unix.stackexchange.com/questions/338000/bash-assign-output-of-pipe-to-a-variable
https://unix.stackexchange.com/questions/574920/bash-how-to-get-stdout-to-console-and-also-pipe-to-next-command
EDIT:
Okay, well, after extended discussion with #juanpa.arrivillaga, he explained that strings are not plain strings as in Bash. Let's see if I have this right.. they are string objects stored in dict objects. (even integers are stored as objects unless using numpy or pandas which expand on Python arrays). Inside a for i in dict1: loop print(i) works because 'print will call str implicitly on any object you pass to it'. i = value does not because 'think of variables as nametags you throw on objects' and i is being resolved in its for loop scope as a dict object key. I'm not sure why, but variable 'nametags' cannot be string objects.
A workaround using globals() kind of mentioned in the Duplicate answers exists:
for key in dict1: globals()[key] = pd.DataFrame()
This is because in CPython, they used actual python objects to implement the global namespaces. It might be possible to 'maybe use ctypes to modify the namespace array in a local scope', as another workaround is to use SimpleNamespace to create a new object to store variables (presumably because they are stored as objects, the same as in globals(). And to wrap up, 'setattr(sys.modules[_name_], var_name, var_value) is equivalent to globals()[var_name] = var_value'.
Sorry it's quite hard to understand what exactly the question is.
for i in dict1: function(i) = dict[key]
A couple of problems with this: the thing on the left is what you're assigning, so the syntax should be dict[key] = function(i) (but don't call your dicts 'dict' because that's a reserved keyword). This is assuming key is defined somewhere. This is why you're getting the error you describe - you cant assign to a function call, you assign to variables.
As for storing things in list, you can put whatever you like in there, same with dictionaries. For example:
import pandas as pd
ls = [pd.DataFrame(), 'Hello']
d = {
'a': pd.DataFrame(),
1: pd.DataFrame()
}
print(ls)
print(d['a'])
print(d[1])
I think this issue can be solved with dictionaries:
var_names = ['your_string', 'your_second_string']
dict = {}
for i, var_name in enumerate(var_names):
var_name = f'var_name{i}'
dict[var_name] = pd.DateFrame([])
This question already has answers here:
How do I create variable variables?
(17 answers)
How can I create multiple variables from a list of strings? [duplicate]
(2 answers)
generating variable names on fly in python [duplicate]
(6 answers)
Closed 3 years ago.
I have a ticker and I want to check a specific list of tickers to see if the ticker is found. If it is found, it will replace it.
The new tickers come from another data source and therefore do not know which specific list of tickers to check. In order to find that list, I can pass the lists name as a string but upon iterating the code (naturally) recognizes this as string as opposed to a list to iterate.
Is there a way to have the code/function recognize that the string is actually a specific list to be checked? In reading other questions, I know this may not be possible...in that case what is an alternative?
list_1=['A','B']
list_2=['C','D']
old_ticker='A'
new_ticker='E'
assigned_list='list_1'
def replace_ticker(old_ticker,new_ticker,list):
for ticker in list:
if new_ticker in list:
return
else:
list.append(new_ticker)
list.remove(old_ticker)
replace_ticker(old_ticker,new_ticker,assigned_list)
You key the needed lists by name in a dictionary:
ticker_directory = {
"list_1": list_1,
"list_2": list_2
}
Now you can accept the name and get the desired list as ticker_directory[assigned_list].
list_1=['A','B']
list_2=['C','D']
lists = {
'list_1':list_1,
'list_2':list_2
}
old_ticker='A'
new_ticker='E'
assigned_list='list_1'
def replace_ticker(old_ticker,new_ticker,list_name):
if old_ticker not in lists[list_name]:
return
else:
lists[list_name].append(new_ticker)
lists[list_name].remove(old_ticker)
replace_ticker(old_ticker,new_ticker,assigned_list)
print(lists[assigned_list])
This is the complete program from what i perceived.
#prune already answered this, I have just given the whole solution
There are at least two possibilities:
1 As noted in comments kind of overkill but possible:
Use eval() to evaluate string as python expressions more in the link:
https://thepythonguru.com/python-builtin-functions/eval/
For example:
list_name = 'list_1'
eval('{}.append(new_ticker)'.format(list_name))
2 Second
Using locals() a dictionary of locally scoped variables similiar to the other answers but without the need of creating the dict by hand which also requires the knowledge of all variables names.
list_name = 'list_1'
locals()[list_name].append(new_ticker)
I'm trying to create a random string of numbers saved to a list, then rename the list further in the code. I've tried using dictionaries to store the names but that didn't work, I've also tried simply newListName=oldListName which when I attempted to print newListName it returns a NameError
You can copy the list into a new one as:
newListName=oldListName[:]
This would not give you the NameError!
Make sure that oldListName is defined as list before and then copied into another list.
This question already has answers here:
Why doesn't assigning to the loop variable modify the original list? How can I assign back to the list in a loop? [duplicate]
(4 answers)
Closed 5 months ago.
I have a list and want to change its elements
list = ['apple','potato']
Now, while this works
for i in range(list):
list[i] = list[i].capitalize()
this one doesn't and I just don't get why
for i in list:
i = i.capitalize()
I'm new to Python, my only background is C++ so I'm still trying to adapt to Python's style. If this kind of question had already been asked, please, feel free to redirect me and close this topic. Thank you!
Assigning in the loop will create a new name i inside the for that loses its value after each iteration.
That isn't really the point here though. You can have the effect get noticed if you were dealing with mutable substructures that can be altered in-place, i.e:
l = [[1], [2]]
for i in l:
i.append(2)
changes will get reflected accordingly (sub-list will be get 2 appended to them).
in your case, though, you have strs which are immutable objects. i.capitalize(), acting on a str instance will create a new copy of the value which is assigned and then lost. It will not affect the objects inside the list.
The value i in for i in container: does refer to the objects contained in the sequence. When you assign i to the result of i.capitalize(), the name i will now refer to the new capitalized instance returned.
Don't try and draw parallels between C++ and Python, I know it sometimes makes learning easier but, other times, in can confuse the hell out of you.
Mandatory note: don't use list as a name, it masks the built-in name list.