简体   繁体   中英

Python: creating a variable using retrieved string name

This may be convoluted/unsafe, but I'd appreciate if someone could let me know if there is a way to do the following in Python or not.

1) Using a list of strings (henceforth called the alpha list), I would like to create other list variables named after the strings.

2) I'd like to be able to manipulate (but primarily append values to) these new list variables without calling them explicitly, ie calling them using the alpha list's indexes so that I can run them through a loop.

Below I'll provide code that hopefully conveys more clearly what I'm trying to do.

#1
alphaString = ['a', 'b', 'c', 'd', 'e']
for letter in alphaString:
    letter = []

#2
rowOfValues = ["alpha", "bravo", "charlie", "delta", "echo"] 
#Length of rowOfValues supposed to be same length as alphaString
#There would be many rows being run through a bigger loop that includes this code, but I'll keep it to just this one row for simplicity

for i in range (0, len(alphaString)):
    if rowOfValues[i] not in alphaString[i]: #Ex. if "alpha" not in list a
            alphaString[i].append(rowOfValues[i]) #Ex.  a.append("alpha")

Is what I'm trying to do not possible with Python, or am I just going about it the wrong way? Thank you!

You can do this in Python by tinkering with the dict that holds local or global variables, locals() and globals() . However, manipulating these structures is considered dangerous and in some cases it may not work as the programmer (or a later person reading the code) expects.

Usually, when a program needs to associate a particular string name with some value, the right Python data structure is a dict that uses the string values as the keys. In your case it could look like this:

letter_dict = {}
alphaString = ['a', 'b', 'c', 'd', 'e']
for letter in alphaString:
    letter_dict[letter] = []

rowOfValues = ["alpha", "bravo", "charlie", "delta", "echo"] 
#Length of rowOfValues supposed to be same length as alphaString
#There would be many rows being run through a bigger loop that includes this code, but I'll keep it to just this one row for simplicity

for i in range (0, len(alphaString)):
    if rowOfValues[i] not in letter_dict[alphaString[i]]: #Ex. if "alpha" not in list a
            letter_dict[alphaString[i]].append(rowOfValues[i]) #Ex.  a.append("alpha")

At the end, letter_dict would have entries such as:

{'a': ['alpha'], 'b': ['bravo'], ...}

There are much cleaner ways to write the code you have in your example as well, using dictionary comprehensions, for example. And if you need to reference the entire set of names that have been associated, you can just request the list of keys from the dictionary: letter_dict.keys() .

The Python standard library collections also has a special kind of dict called defaultdict . This kind of data structure accepts a function that can be called whenever a particular key is not already found in the dictionary. If you chose to use that structure, you could get rid of the need to initialize the empty lists explicitly as you do:

from collections import defaultdict

# Make an empty dict where, if a key is requested and not found, an empty list
# will be stored for that key as the default.
letter_dict = defaultdict(lambda: []) 

Then you can skip the loop of for letter in alphaString .

So it should be possible, only it would take some time figuring out how to do it (with dicts and eval maybe?), but it would be messy and unsafe.

This is a simple oneliner that (I think)does the job (I'm still not completely sure what you want).

dict(zip(alphaString,map(lambda x: [x],rowOfValues)))

This does not, however, make the values unique. But with some playing with for loops, set and lambda that shouldn't be a problem.

Indeed, a dictionary structure, as suggested by @EMS is probably best suited. However, you can probably use the exec command for creating variables on the fly using string. For example, if you wish to set a=3 from a string, you can do.

exec('a=3')

In your case, you might want to try

nameList = ['a','b','c','d','e']
varList = []
for name in nameList:
    exec(name+'=[]') 
    exec('varList.append('+name+')')

etc...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM