与使用 2 个文本文件的双循环相比,使用 2 个列表的双循环 - 不同的结果
Double for Loop Using 2 Lists Compared to Double Loop Using 2 Text Files - Different Outcome
所以我有 2 个迷你脚本。 1 产生我期望的输出,另一个没有。产生我预期的输出的第一个代码:
with open('cities.txt', 'r') as cities, \
open('test_file.txt', 'r') as test:
space = " "
city_lst = []
test_lst = []
for c in cities:
city_lst.append(c)
for t in test:
test_lst.append(t)
for city in city_lst:
for tes in test_lst:
print city.rstrip(),space,tes.rstrip()
输出(如我所料):
san diego san diego is the best place
san diego Then there is new york state
san diego And now we have tuscon in arizona
san francisco san diego is the best place
san francisco Then there is new york state
san francisco And now we have tuscon in arizona
tuscon san diego is the best place
tuscon Then there is new york state
tuscon And now we have tuscon in arizona
pheonix san diego is the best place
pheonix Then there is new york state
pheonix And now we have tuscon in arizona
sedona san diego is the best place
sedona Then there is new york state
sedona And now we have tuscon in arizona
baton rouge san diego is the best place
baton rouge Then there is new york state
baton rouge And now we have tuscon in arizona
在下一段代码中,我没有得到我想要的输出。它与上面的代码基本相同,只是我直接使用文本文件而不是先将它们转换为列表。但是,令我困惑的是为什么我没有得到完全相同的输出。
代码:
with open('cities.txt', 'r') as cities, \
open('test_file.txt', 'r') as test:
space = " "
for c in cities:
for t in test:
print c.rstrip(), space, t.rstrip()
输出:
san diego san diego is the best place
san diego Then there is new york state
san diego And now we have tuscon in arizona
因为我在每个代码中都使用相同的 double for 循环,使用相同的 print 语句,为什么输出有差异?
以下是文本文件的内容:
cities.txt:
san diego
san francisco
tuscon
pheonix
sedona
baton rouge
test_file.txt:
san diego is the best place
Then there is new york state
And now we have tuscon in arizona
因为文件是迭代器,而列表就是列表。
当你做的时候
for t in test:
pass # do anything here
到该循环结束时,您已经用完了迭代器。里面什么都没有了!自己试试吧!:
with open('testfile.txt') as inf:
for line in inf:
print("There's a line here, I'm reading!")
for line in inf:
print("Turn lead into gold")
你会发现这里完全没有炼金术。
您可以做的是在每次读取文件之前seek
回到文件的开头。
for c in cities:
test.seek(0)
# place the pointer at the beginning of the file
for t in test:
frobnicate_stuff()
不过,我更喜欢读取每个文件一次并对列表进行操作,就像您在上面的示例中所做的那样。你可以用 itertools.product
:
做得更好
import itertools
with open('cities.txt') as cities, \
open('test.txt') as test:
city_lst = cities.readlines()
test_lst = test.readlines()
for c, t in itertools.product(city_lst, test_lst):
print(c.rstrip() + " " + t.rstrip())
# or using string formatting:
# # print("{} {}".format(c.rstrip(), t.rstrip()))
编辑
事实上,进一步的测试表明 itertools.product
在使用每个迭代器之前将其内部化!这意味着我们可以做:
with open('cities.txt') as cities, \
open('tests.txt') as tests:
for c, t in itertools.product(cities, tests):
print(c.rstrip() + " " + t.rstrip())
因为文件的对象是迭代器。要将其转换为列表,请使用 .readlines()
函数。你的代码应该是这样的:
with open('cities.txt') as cities, open('tests.txt') as tests:
for c in cities.readlines()
for t in tests.readlines():
print(c.rstrip() + " " + t.rstrip())
或者,您也可以使用 itertools.product()
来防止嵌套循环。在这种情况下,您的代码应该是这样的:
with open('cities.txt') as cities, open('tests.txt') as tests:
for c, t in itertools.product(cities.readlines(), tests.readlines()):
print("{city} {test}".format(city=c,test=t))
注意:不要使用 +
直接附加字符串。使用 .format()
方法更好。
所以我有 2 个迷你脚本。 1 产生我期望的输出,另一个没有。产生我预期的输出的第一个代码:
with open('cities.txt', 'r') as cities, \
open('test_file.txt', 'r') as test:
space = " "
city_lst = []
test_lst = []
for c in cities:
city_lst.append(c)
for t in test:
test_lst.append(t)
for city in city_lst:
for tes in test_lst:
print city.rstrip(),space,tes.rstrip()
输出(如我所料):
san diego san diego is the best place
san diego Then there is new york state
san diego And now we have tuscon in arizona
san francisco san diego is the best place
san francisco Then there is new york state
san francisco And now we have tuscon in arizona
tuscon san diego is the best place
tuscon Then there is new york state
tuscon And now we have tuscon in arizona
pheonix san diego is the best place
pheonix Then there is new york state
pheonix And now we have tuscon in arizona
sedona san diego is the best place
sedona Then there is new york state
sedona And now we have tuscon in arizona
baton rouge san diego is the best place
baton rouge Then there is new york state
baton rouge And now we have tuscon in arizona
在下一段代码中,我没有得到我想要的输出。它与上面的代码基本相同,只是我直接使用文本文件而不是先将它们转换为列表。但是,令我困惑的是为什么我没有得到完全相同的输出。
代码:
with open('cities.txt', 'r') as cities, \
open('test_file.txt', 'r') as test:
space = " "
for c in cities:
for t in test:
print c.rstrip(), space, t.rstrip()
输出:
san diego san diego is the best place
san diego Then there is new york state
san diego And now we have tuscon in arizona
因为我在每个代码中都使用相同的 double for 循环,使用相同的 print 语句,为什么输出有差异?
以下是文本文件的内容: cities.txt:
san diego
san francisco
tuscon
pheonix
sedona
baton rouge
test_file.txt:
san diego is the best place
Then there is new york state
And now we have tuscon in arizona
因为文件是迭代器,而列表就是列表。
当你做的时候
for t in test:
pass # do anything here
到该循环结束时,您已经用完了迭代器。里面什么都没有了!自己试试吧!:
with open('testfile.txt') as inf:
for line in inf:
print("There's a line here, I'm reading!")
for line in inf:
print("Turn lead into gold")
你会发现这里完全没有炼金术。
您可以做的是在每次读取文件之前seek
回到文件的开头。
for c in cities:
test.seek(0)
# place the pointer at the beginning of the file
for t in test:
frobnicate_stuff()
不过,我更喜欢读取每个文件一次并对列表进行操作,就像您在上面的示例中所做的那样。你可以用 itertools.product
:
import itertools
with open('cities.txt') as cities, \
open('test.txt') as test:
city_lst = cities.readlines()
test_lst = test.readlines()
for c, t in itertools.product(city_lst, test_lst):
print(c.rstrip() + " " + t.rstrip())
# or using string formatting:
# # print("{} {}".format(c.rstrip(), t.rstrip()))
编辑
事实上,进一步的测试表明 itertools.product
在使用每个迭代器之前将其内部化!这意味着我们可以做:
with open('cities.txt') as cities, \
open('tests.txt') as tests:
for c, t in itertools.product(cities, tests):
print(c.rstrip() + " " + t.rstrip())
因为文件的对象是迭代器。要将其转换为列表,请使用 .readlines()
函数。你的代码应该是这样的:
with open('cities.txt') as cities, open('tests.txt') as tests:
for c in cities.readlines()
for t in tests.readlines():
print(c.rstrip() + " " + t.rstrip())
或者,您也可以使用 itertools.product()
来防止嵌套循环。在这种情况下,您的代码应该是这样的:
with open('cities.txt') as cities, open('tests.txt') as tests:
for c, t in itertools.product(cities.readlines(), tests.readlines()):
print("{city} {test}".format(city=c,test=t))
注意:不要使用 +
直接附加字符串。使用 .format()
方法更好。