关于python(文件)的一些问题

时间:2013-11-18 21:23:01

标签: python algorithm file

我是新来的,我也是python的新手。我想得到你的帮助。

def lines(path, prefix):
  funf = open(path, 'r')
  dictionary = {}
  for lines in funf:
     word = lines.split()
     a_word = (word[0])
     dictionary[a_word] = dictionary.get(a_word, 0) + 1
  if prefix != word[0]:
     return 0
  else:
     return dictionary[prefix]
  funf.close()

当我运行时:

    inpath = "filetext1.txt"
    print(lines(inpath,"But"))

我得到了这个:

 Traceback (most recent call last):
 File "C:...\...\....py", line 29, in <module>
 print(lines(inpath,"This"))
 File "C:...\...\....py", line 11, 
 in lines
if prefix != word[0]:
UnboundLocalError: local variable 'word' referenced before assignment

问题是什么,如何更改它会更好? 我要求提出想法和选择(但请在不改变代码中的更多内容的情况下......它必须是这样的结构!!!

谢谢!

2 个答案:

答案 0 :(得分:2)

在您的代码中,if prefix != words[0]部分在循环完成运行后在循环外部发生。因此,对于非空文件,words将是文件最后一行的拆分。对于空文件,words将永远不会被设置,从而导致您发布的错误。

作为旁注,for lines in f:循环遍历某个全局对象f,而不是您刚打开的文件,称为funf。因此,我怀疑f是某种空迭代,即使您想要查看的文件为空,您也会看到此函数。如果您想循环funf,则必须告诉Python funf,而不是f

你已经知道这是不正确的,如本评论所述:

  

字是线的分裂。我不能在for循环之外做到这一点

如果要在循环中运行,则需要缩进它以匹配循环内的代码。在Python中,块结构基于缩进级别:

def lines(path, prefix):
    funf = open(path, 'r')
    dictionary = {}
    for lines in f:
        word = lines.split()
        a_word = (word[0])
        dictionary[a_word] = dictionary.get(a_word, 0) + 1
        if prefix != word[0]:
            return 0
        else:
            return dictionary[prefix]
    funf.close()

这意味着你不会再出错了; <{1}}将始终在您使用时定义。

此代码存在其他问题:您在每行之后words,这意味着您永远不会到达第二行;在关闭文件之前你是return,这意味着文件永远不会被关闭;对于单个事物使用多个变量名称和为事物列表使用单个变量名称是非常误导的;使用与函数同名的局部变量令人困惑;等。但有一件事......


经过半个小时的拔牙,你终于解释了你要做的事情:

  

我正在尝试计算第一个单词与前缀匹配的行数

这种结构无法做到这一点。无论你在循环内部进行return还是外出,都没有任何意义。

解决此问题的最简单方法是完全删除if。你正在建立一个每个第一个单词的计数字典,对吧?所以,只需在最后查找给定前缀的值:

if

这样可以工作,但是构建整个字典只是为了从中获取单个值,并且使你的代码变得更加复杂,这是非常浪费的......整个事情可以写成:

def lines(path, prefix):
    funf = open(path, 'r')
    dictionary = {}
    for lines in funf:
        word = lines.split()
        a_word = (word[0])
        dictionary[a_word] = dictionary.get(a_word, 0) + 1
    funf.close()
    return dictionary.get(prefix, 0)

这是我的filetext1.txt:

def lines(path, prefix):
    with open(path) as f:
        return sum(1 for line in f if line.startswith(prefix))

输出显然应为2,对吗?

我的代码的两个版本 - “最简单的修复”和双线版 - 都打印出来:

This is a test.
But this isn't.
But this is.
And this isn't.

这适用于Python 3.3和2.7。如果它不适合您,要么您复制并粘贴代码失败,要么您的输入文件没有以2 开头的任何行。

答案 1 :(得分:0)

如果你试图计算第一个单词与前缀匹配的行数,为什么不做一些像

这样简单的事情。
def lines(path, prefix):
    N_matches = 0
    f = open(path, 'r')
    for line in f:
        words = line.split()
        first_word = words[0]
        if first_word == prefix:
            N_matches += 1
    f.close()
    return N_matches

这也可以通过更少的代码完成:

def lines(path, prefix):
    with open(path, 'r') as f:
        return sum([1 for line in f if line.split()[0] == prefix])

正如@abarnert所指出的,更好的方法是

        return sum(1 for line in f if line.startswith(prefix))