使用Python的exec()函数和格式化的字符串?

时间:2015-11-22 20:51:26

标签: python list exec

我有一个包含学校日程安排的文件,我想从文件的每一行创建一个列表。该文件看起来像这样:

first:second:third:fourth:fifth
first:second:third:fourth:fifth

代码是这样的:

schedule_file = "school-schedule.txt"
with open(schedule_file) as schedule:
    for c, line in enumerate(schedule):
        exec("ln%s = schedule.read().split(':')" % str(c+1))

print(ln1)
print(ln2)
print(ln3)
print(ln4)
print(ln5)
print(ln6)
print(ln7)
print(ln8)
print(ln9)
print(ln10)

我知道该文件有十行,这就是为什么出于测试目的,我希望它打印这十个列表。不幸的是,它似乎将第一行放入名为ln1的列表中,并从ln2开始为所有其他列表引发NameError异常:

['first', 'second', 'third', 'fourth', 'fifth']
Traceback (most recent call last):
  File "D:\schedule.py", line 10, in <module>
    print(ln2)
NameError: name 'ln2' is not defined

是不是可以在exec()函数中使用格式化字符串,还是我犯了其他一些愚蠢的错误?

2 个答案:

答案 0 :(得分:2)

for c, line in enumerate(schedule):
    exec("ln%s = schedule.read().split(':')" % str(c+1))

文件中的行在变量line中,但你写了:

exec("ln%s = schedule.read().split(':')....

而不是:

exec("ln%s = line.split(':')...

在任何情况下,每当你发现自己编写如下名字的变量时:

print(ln1)
print(ln2)
print(ln3)
print(ln4)

如果变量名只有一个数字,那么你需要停止你正在做的事情,而是使用一个列表。如果您有一个名为ln的列表,则列表中的项目已经具有名称ln[0], ln[1]等。因此,您可以执行此操作:

with open('data.txt') as f:
      ln = [line.rstrip().split(':') for line in f]

print(ln)
print(ln[0])
print(ln[1])

--output:--
$ cat data.txt
a:b:c:d
e:f:g:h

$ python prog.py
[['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h']]
['a', 'b', 'c', 'd']
['e', 'f', 'g', 'h']

答案 1 :(得分:1)

您在第一次迭代后阅读了整个文件,因此您永远不会超过第一个exec("ln%s = .....

exec("ln%s = schedule.read().split(':')" % str(c+1))
                      ^^^
                     .read() # reads whole/rest of file

只需使用readlines并按索引访问:

with open(schedule_file) as schedule:
    data = schedule.readlines()
ln1 = data[0].split(":")
.....

或与地图结合分割:

data = list(map(lambda x: x.split(":"),schedule))

你也可以使用dict,但它不仅仅是简单地使用列表和按索引访问的好处。

如果你真的想要十个变量,那么解压缩:

 with open(schedule_file) as schedule:
    ln1,ln2 ....ln10 = map(lambda x: x.split(":"),schedule