来自字符串的Python名称变量

时间:2012-06-20 18:52:13

标签: python list variables dictionary naming

是否可以根据字符串的值创建变量名称?

我有一个脚本,它将读取文件中的信息块并将它们存储在字典中。然后将每个块的字典附加到“主”字典中。文件中的信息块数量会有所不同,并使用“完成”一词来表示块的结束。

我想做这样的事情:

master={}
block=0
for lines in file:
  if line != "done":
    $block.append(line)
  elif line == "done":
    master['$block'].append($block)
    block = block + 1

如果文件的内容如此:

eggs
done
bacon
done
ham
cheese
done

结果将是一个包含3个列表的字典:

master = {'0': ["eggs"], '1': ["bacon"], '2': ["ham", "cheese"]}

如何实现这一目标?

5 个答案:

答案 0 :(得分:3)

我实际上建议您改用列表。有什么特别的说法,为什么你需要arrayt ish的dicts?

如果你可以使用数组,你可以使用它:

with open("yourFile") as fd:
    arr = [x.strip().split() for x in fd.read().split("done")][:-1]

输出:

[['eggs'], ['bacon'], ['ham', 'cheese']]

如果您想要数字字符串索引,可以使用:

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)

您似乎误解了字典的工作原理。他们把钥匙当作物体,所以这里不需要魔法。

但是,我们可以使用collections.defaultdict根据需要制作子列表,从而使代码更好。

from collections import defaultdict

master = defaultdict(list)
block = 0
for line in file:
    if line == "done":
        block += 1
    else:
        master[block].append(line)
但是,如果你想要连续的编号索引,我会建议不需要字典 - 这就是列表的用途。在这种情况下,我建议您关注Thrustmaster's first suggestion,或者作为替代方案:

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

答案 2 :(得分:1)

我认为对“完成”的分裂注定要失败。考虑清单:

eggs
done
bacon
done
rare steak
well done stake
done

从Thrustmaster偷窃(我为我的盗窃罪给了+1)我建议:

>>> dict(enumerate(l.split() for l in open(file).read().split('\ndone\n') if l))
{0: ['eggs'], 1: ['bacon'], 2: ['ham', 'cheese']}

我知道这需要一个尾随的“\ n”。如果有问题,你可以使用“open(file).read()+'\ n'”甚至“+'\ n \ ndone \ n'”如果最终完成是可选的。

答案 3 :(得分:0)

使用setattr或globals()。
How do I call setattr() on the current module?

答案 4 :(得分:0)

这是你的代码,对于并置:

master={}
block=0
for lines in file:
  if line != "done":
    $block.append(line)
  elif line == "done":
    master['$block'].append($block)
    block = block + 1

正如Thrustmaster在帖子中所提到的,在这里使用嵌套列表更有意义。这是你如何做到的;我从原始代码中以尽可能少的结构改变了:

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

这里唯一的事情就是你最终会在master列表的末尾添加一个额外的列表,所以你应该在del添加一行代表最后一个空的子列表:< / p>

del master[-1]