-1

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'.

alchemy
  • 954
  • 10
  • 17
  • "Is there anyway to set a variable value using something other than a plain string" I have no idea what you are asking. Variables aren't strings. Are you asking how to dynamically create variables? – juanpa.arrivillaga Apr 03 '20 at 07:21
  • @juanpa.arrivillaga, I updated the title to be more clear. I meant that the variable 'name' meaning what it is called, is something other than a plain string. Meaning using the string output of a function such as str(s), where s could be a dict key, list item or other string. Or simply using dict key, list item, etc.. neither of which works. – alchemy Apr 03 '20 at 17:33
  • So you do mean dynamically creating variables? Don't do that. Use a *container*, like a list or a dict. – juanpa.arrivillaga Apr 03 '20 at 17:51
  • @juanpa.arrivillaga, you could call it that. Its adolescent and useless to tell people what to do, there is a reason I asked. Obviously, using a dict is a popular solution. It isnt as efficient as 'dynamically' creating one if only one or two variables are needed. There are other solutions in the Duplicate Question that may work including using the var() or global() functions concisely, and possibly using `setattr(sys.modules[__name__], var_name, var_value)`. – alchemy Apr 03 '20 at 18:12
  • 1
    No, I'm just providing you with best practices. That is the whole point of this website, actually, giving people suggestions about what to do with their code. You are free to ignore that and write unclean, hacky code all you want, like those examples you mentioned (which will only work in the global scope in CPython as an implementation detail). – juanpa.arrivillaga Apr 03 '20 at 18:15
  • @juanpa.arrivillaga, whatever, then just say that.. No need to judge something hacky without stating a full reason. I'm not using CPython, but good to know. The setattr one might actually be the equivalent to the Bash functionality.. aw, but Bash Read must be 'hacky', right? Its only the model for much of Python. Interesting that both use # for commenting, etc. – alchemy Apr 03 '20 at 18:41
  • Look, you need to understand that this website is about *everyone*. If someone asks "how do I interpolate my string from user input into a SQL query", you better believe the comments will be inundated with **don't do that**. I'm not sure how you figure bash Read is equivalent here, read is closer to `input()` in Python. And no, bash is not the model for Python at all. Maybe some aspects of the syntax are superficially similar (like using # for comments). And yes, I would characterize a lot of bash as hacky, at least the way it is commonly used, and that makes sense for a shell language – juanpa.arrivillaga Apr 03 '20 at 18:49
  • @juanpa.arrivillaga, Ill move this to chat because you seem to want to defend your comment. But 'everyone else does it' isnt a great argument. What Read does is be able to take the output of one command and assign a variable name to it `var1='a'; echo $a | { read var2; echo "$var2";}` That is more powerful than Python in this case. Also, Python was a massive shift to interpreted languages, mimicking the non-compilation of shell scripts. ..Im just trying to assign a dataframe to a variable name that is in a set of dict keys, no need to get bent out of shape. – alchemy Apr 03 '20 at 19:21
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210893/discussion-between-juanpa-arrivillaga-and-alchemy). – juanpa.arrivillaga Apr 03 '20 at 19:27

2 Answers2

0

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([])
gosuto
  • 5,422
  • 6
  • 36
  • 57
  • no, but I edited it for better clarity, I hope – alchemy Apr 02 '20 at 23:19
  • can you add some code so the question is more clear? I'm not really sure what you're after – mcindoe Apr 02 '20 at 23:23
  • Im trying to get this to work: `for i in dict1: i = pd.dataframe()`, where the dict1 is names and dataframes. It should end with multiple dataframes that can be called by name, like the standard `name = pd.dataframe(); name` which outputs the dataframe. – alchemy Apr 03 '20 at 00:14
0

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])
mcindoe
  • 101
  • 2
  • 8
  • hi, yes, I state that doesnt work.. Im looking for a solution that does, and it was just an idea as a work around for this `for i in dict1: i = dict1[key]`, where the value of dict1[key] is a dataframe – alchemy Apr 02 '20 at 23:18