2015-11-22 61 views
1

我有一個包含我的學校時間表的文件,我想從文件中的每一行創建一個列表。該文件看起來是這樣的:使用具有格式化字符串的Python的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列表,並提出了一個NameError異常所有其他列表,從ln2

['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()函數內部還是我我犯了一些其他愚蠢的錯誤?

+3

你錯就錯在使用'EXEC()'。不惜一切代價避免它。而不是試圖動態製作10個變量,只需使用字典。 – MattDMo

回答

1
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'] 
+0

謝謝你。正如我在第一個答案下所說的,我不確定爲什麼我需要十個變量。使用列表要容易得多,絕對更優雅。 –

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

你也可以使用字典,但它不是真正的除了簡單地使用列表和通過索引訪問之外,它將會有什麼好處。

如果你真的想10個變量,然後解壓:

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

謝謝。使用readlines和索引訪問比我想象的要容易得多。有很多要學習:) 再次感謝! –

+0

不用擔心,第一次爲所有的東西:) –