这是我差不多完成的作业。所以我们的目标是能够根据CID搜索列表,这是txt文件每行中的第一个值。
文本文件包含以下记录,并以制表符分隔:
0001 001 -- -- 1234.00 -- -- 148.08 148.08 13.21 1395.29
0002 011 -- 100.00 12000.00 -- 5.00 1440.00 1445.00 414.15 13959.15
0003 111 100.00 1000.00 1000.00 8.00 50.00 120.00 178.00 17.70 2295.70
0004 110 1200.00 100.00 -- 96.00 5.00 -- 101.00 6.15 1407.15
0005 101 100.00 -- 1300.00 8.00 -- 156.00 164.00 15.60 1579.60
0006 100 1200.00 -- -- 96.00 -- -- 96.00 5.40 1301.40
0007 010 -- 1500.00 -- -- 75.00 -- 75.00 2.25 1577.25
0008 001 -- -- 1000.00 -- -- 120.00 120.00 9.00 1129.00
0009 111 1000.00 1000.00 1000.00 80.00 50.00 120.00 250.00 28.50 3278.50
0010 111 100.00 10000.00 1000.00 8.00 500.00 120.00 628.00 123.90 11851.90
可以找到文本文件here。
我是Python的新手,还没有理解它。我需要能够以某种方式动态填充lines[0]
与其他索引位置。例如......在索引[0]中找到'0002',如果我改为lines[1]
则找到0002,依此类推。我尝试了各种各样的方法,枚举,列表理解,但大部分都超出了我的理解范围。或者可能有一种更简单的方法来显示特定“客户”的行?
with open('customer.txt', 'r') as file:
for line in file:
lines = file.read().split('\n')
search = input("Please enter a CID to search for: ")
if search in lines[0]:
print(search, "was found in the database.")
CID = lines[0]
print(CID)
else:
print(search, "does not exist in the database.")
答案 0 :(得分:2)
不确定,这些线应该以某种方式分割成字段吗?
search = input("Please enter a CID to search for: ")
with open('customer.txt', 'r') as file:
for line in file:
fields = line.split('\t')
if fields[0] == search:
print(search, "was found in the database.")
CID = fields[0]
print(line)
break
else:
print(search, "does not exist in the database.")
答案 1 :(得分:1)
我认为你应该如何解决这个问题。代码下方的评论。
_MAX_CID = 9999
while True:
search = input("Please enter a CID to search for: ")
try:
cid = int(search)
except ValueError:
print("Please enter a valid number")
continue
if not 0 <= cid <= _MAX_CID:
print("Please enter a number within the range 0..%d"% _MAX_CID)
continue
else:
# number is good
break
with open("customer.txt", "r") as f:
for line in f:
if not line.strip():
continue # completely blank line so skip it
fields = line.split()
try:
line_cid = int(fields[0])
except ValueError:
continue # invalid line so skip it
if cid == line_cid:
print("%d was found in the database." % cid)
print(line.strip())
break
else:
# NOTE! This "else" goes with the "for"! This case
# will be executed if the for loop runs to the end
# without breaking. We break when the CID matches
# so this code runs when CID never matched.
print("%d does not exist in the database." % cid)
我们不是搜索文本匹配,而是将用户的输入解析为数字并搜索数字匹配。因此,如果用户输入0,则文本匹配将匹配示例文件的每一行,但数字匹配不匹配任何内容!
我们接受输入,然后将其转换为整数。然后我们检查它是否有意义(不是负面或太大)。如果它没有通过任何测试我们继续循环,让用户重新进入。一旦它成为有效数字,我们就会脱离循环并继续。 (您的老师可能不喜欢我在这里使用break
的方式。如果它让您的老师更开心,请添加一个名为done
的变量,该变量最初设置为False
,并将其设置为{{ 1}}当输入验证时,并使循环True
)。
你似乎对输入感到有些困惑。当您打开文件时,您将返回一个表示已打开文件的对象。你可以做这个对象的几件事。您可以做的一件事是使用方法函数,如while not done:
或.readlines()
,但您可以做的另一件事就是迭代它。要迭代它,你只需将它放在.read()
循环中;当你这样做时,每个循环迭代从文件中获得一行输入。所以我的代码示例每次都将变量for
设置为文件中的一行。如果你使用line
方法,你可以将整个文件放入内存中,一次性完成,这是不需要的;然后你的循环不会循环遍历文件的行。通常你应该使用.read()
种循环;有时您需要使用for line in f:
来覆盖文件;你永远不会同时做这两件事。
这是一个小问题,但是f.read()
是Python中的内置类型,通过分配给你重新绑定名称,以及&#34; shadowing&#34;内置类型。为什么不像我在程序中那样简单地使用file
?或者,使用f
之类的内容。当我同时拥有输入文件和输出文件时,我通常使用in_file
和in_file
。
获得该行后,我们可以使用out_file
方法函数将其拆分为字段。然后代码强制第0个字段为整数并检查完全匹配。
此代码检查输入行,如果它们不起作用,则以静默方式跳过该行。那是你要的吗?也许不吧!如果数据库文件格式错误,代码爆炸可能会更好。然后,您可能希望输入.split()
语句而不是使用continue
语句,并引发异常。也许定义你自己的raise
异常,我认为它应该是MalformedDatabase
的子类。
此代码使用Python的一个非常独特的功能,即ValueError
循环上的else
语句。这适用于仅在循环一直运行到最后时执行的代码,而不会提前退出。当循环找到客户ID时,它会以for
语句提前退出;当从未找到客户ID时,循环将运行到最后并执行此代码。
这段代码实际上可以正常使用Python 2.x,但错误检查并不合适。如果你在Python 3.x下运行它,那就很好了。我假设你使用Python 3.x来运行它。如果你使用Python 2.x运行它,输入break
或像xxx
这样的疯狂垃圾,你会得到不同的例外而不仅仅是被测试的0zz
! (如果你真的想在Python 2.x中使用它,你应该将ValueError
更改为input()
,或者在raw_input()
/ try
中捕获更多例外。)
答案 2 :(得分:0)
另一种方法。由于文件是制表符分隔的,因此您也可以使用csv
module。
与@ gnibbler的答案不同,这种方法将读取整个文件,然后搜索其内容(因此它会将文件加载到内存中)。
import csv
with open('customer.txt') as file:
reader = csv.reader(file, delimiter='\t')
lines = list(reader)
search = input('Please enter the id: ')
result = [line for line in lines if search in line]
print '\t'.join(*result) if result else 'Not Found'