0

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

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

我想做这样的事情:

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"]}

这怎么可能实现?

4

5 回答 5

3

我实际上建议您改用列表。有没有什么特别的点,为什么你需要数组式的字典?

如果你可以使用数组,你可以使用这个:

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))
于 2012-06-20T18:57:40.937 回答
2

您似乎误解了字典的工作原理。他们拿的是对象的钥匙,所以这里不需要魔法。

但是,我们可以根据需要使用 acollections.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 的第一个建议,或者,作为替代方案:

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)))
于 2012-06-20T18:57:09.943 回答
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'" 。

于 2012-06-20T19:55:50.627 回答
0

使用 setattr 或 globals()。
请参阅如何在当前模块上调用 setattr()?

于 2012-06-20T18:56:55.543 回答
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在最后一个空子列表中添加一行:

del master[-1]
于 2012-06-20T19:30:22.767 回答