如何让它更像Pythonic?

时间:2011-03-13 22:41:41

标签: python path

我正在学习Python。我在Google Code Jam中发现了this问题。并通过编写此代码解决了这个问题。它正常工作但是有什么其他的可能性使这个代码更Pythonic,提高速度或无论如何更好。感谢。

import sys

def split_path(f,c):
    result_list = []
    for i in range(c):
        l = f.readline()
        l = l[1:]
        l = l.strip()
        splited = l.split('/')
        for j in range(1,len(splited)+1):
            joined = "/".join(splited[:j])
            result_list.append(joined)
    return result_list

def main():

    file_name = sys.argv[1]

    if not file_name:
        file_name = "A-small-practice.in"

    f = open(file_name)

    l = f.readline()
    #t = int(l)

    case_no = 0

    while True:
        l = f.readline()

        if not l:
            break

        e,n = l.split()
        e = int(e)
        n = int(n)      

        e_list = split_path(f,e)

        n_list = split_path(f,n)

        new_set = set(n_list) - set(e_list)     

        case_no += 1

        print "Case #%d: %d" % (case_no,len(new_set))

    f.close()   

if __name__ == '__main__':
    main()

3 个答案:

答案 0 :(得分:2)

import sys

def getInts(s):
    "Convert string to list of integers"
    return [int(i) for i in s.strip().split()]

def getPath(s, sep='/'):
    "Convert string to list of directory names"
    dirs = s.strip().split(sep)
    dirs.pop(0)  # remove empty root-dir string
    return dirs

def addPath(tree, path):
    "Recursively add a path to dir tree, return number of dirs added"
    if path:
        this = path.pop(0)
        if this in tree:
            added = 0
        else:
            tree[this] = {}
            added = 1
        return added + addPath(tree[this], path)
    else:
        return 0

def doTest(f):
    "Run one test cycle"
    old,new = getInts(f.next())
    root = {}
    oldDirs = sum(addPath(root, getPath(f.next())) for i in range(old))
    newDirs = sum(addPath(root, getPath(f.next())) for i in range(new))
    return newDirs

def main():
    try:
        fileName = sys.argv[1]
    except IndexError:
        fileName = "A-small-practice.in"

    with open(fileName) as f:
        numTests, = getInts(f.next())
        for test in range(numTests):
            print("Case #{0}: {1}".format(test+1, doTest(f)))

if __name__ == '__main__':
    main()

评论:

  • 有意义的函数名称,变量名称和文档字符串可帮助您弄清楚发生了什么。

  • 功能性编程风格很好 - 简短的单一用途“构建块”功能,没有副作用,可以轻松组合和重复使用。

  • split_path不是一个好的功能名称;看着它,它应该被称为allSubpaths之类的东西,应该返回一个集合(预先删除所有重复项)。

  • 测试很好;你的代码

    file_name = sys.argv[1]
    if not file_name:
        file_name = "A-small-practice.in"
    
    如果没有收到命令行参数,

    将抛出异常;永远不会达到if not file_name

答案 1 :(得分:1)

例如:

使用with使其更具Pythonic:

with open("filename") as f:
    data = f.readline()
    #do something with data

现在你不必关闭任何东西。 Python为你做到了。

答案 2 :(得分:1)

过于开放一个问题,但主观性如此,我会说:

  • 不要重复使用相同的变量来存储不同的值(即l)。另外,不要使用l(因为从第一个开始很难说)。使用有意义的名称:line
  • 将发生器用于split_path
  • 不要无缘无故地插入空白行。