Python name variable from string
本问题已经有最佳答案,请猛点这里访问。
是否可以基于字符串的值创建变量名?
我有一个脚本,它将读取一个文件中的信息块,并将它们存储在字典中。然后将每个块的字典附加到"master"字典中。文件中信息块的数量会有所不同,并使用"完成"一词来指示块的结尾。
我想这样做:
1 2 3 4 5 6 7 8 | master={} block=0 for lines in file: if line !="done": $block.append(line) elif line =="done": master['$block'].append($block) block = block + 1 |
如果文件包含这样的内容:
1 2 3 4 5 6 7 | eggs done bacon done ham cheese done |
号
结果将是一本字典,有3个列表:
1 | master = {'0': ["eggs"], '1': ["bacon"], '2': ["ham","cheese"]} |
这是怎么做到的?
我真的建议你用列表来代替。有没有什么具体的点,为什么你需要数组式的听写?
如果可以使用数组,则可以使用以下命令:
1 2 | with open("yourFile") as fd: arr = [x.strip().split() for x in fd.read().split("done")][:-1] |
输出:
1 | [['eggs'], ['bacon'], ['ham', 'cheese']] |
。
如果需要数字字符串索引,可以使用以下方法:
1 2 3 | with open("yourFile") as fd: l = [x.strip().split() for x in fd.read().split("done")][:-1] print dict(zip(map(str,range(len(l))),l)) |
你似乎误解了字典的工作原理。他们拿的钥匙是物体,所以这里不需要魔法。
但是,我们可以使用
1 2 3 4 5 6 7 8 9 | from collections import defaultdict master = defaultdict(list) block = 0 for line in file: if line =="done": block += 1 else: master[block].append(line) |
不过,我建议,如果你想要连续的、有编号的索引,字典是不必要的——这就是列表的目的。在这种情况下,我建议您遵循Thrustmaster的第一个建议,或者作为一个替代方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 | from itertools import takewhile def repeat_while(predicate, action): while True: current = action() if not predicate(current): break else: yield current with open("test") as file: action = lambda: list(takewhile(lambda line: not line =="done", (line.strip() for line in file))) print(list(repeat_while(lambda x: x, action))) |
号
我认为"完成"的分裂注定要失败。考虑以下列表:
1 2 3 4 5 6 7 | eggs done bacon done rare steak well done stake done |
。
从Thrustmaster偷东西(我偷东西给了+1),我建议:
1 2 3 4 | >>> dict(enumerate(l.split() for l in open(file).read().split(' done ') if l)) {0: ['eggs'], 1: ['bacon'], 2: ['ham', 'cheese']} |
我知道这需要一个尾随的""。如果有问题,可以使用"open(file.read()+''"或甚至"+'行'",如果最后完成是可选的。
这是您的代码,用于并列:
1 2 3 4 5 6 7 8 | master={} block=0 for lines in file: if line !="done": $block.append(line) elif line =="done": master['$block'].append($block) block = block + 1 |
。
正如ThrustMaster在文章中提到的,在这里使用嵌套列表更有意义。以下是您将如何做到这一点的方法;我在结构上尽可能少地更改了您的原始代码:
1 2 3 4 5 6 | master=[[]] # Start with a list containing only a single list for line in file: # Note the typo in your code: you wrote"for lines in file" if line !="done": master[-1].append(line) # Index -1 is the last element of your list else: # Since it's not not"done", it must in fact be"done" master.append([]) |
。
这里唯一的一点是,在您的EDOCX1[1]列表的末尾会有一个额外的列表,因此您应该在EDOCX1[2]中添加一行,以检测最后一个空子列表:
1 | del master[-1] |
使用setattr或globals()。请参阅如何在当前模块上调用setattr()?