2016-11-19 10 views
0

パス内のPythonファイルと非Pythonファイルの数を再帰的に数えようとしています。Pythonは1つの再帰関数で複数のカウンタを保持します

import os 
def main(): 
    #path = input('Enter an existing path to a file or directory: ') 
    path ='/Users/ziyuanhan/PycharmProjects/lab6/' 
    print(count_file(path, counter={'py':0, 'non_py':0})) 

def count_file(path,counter): 
    if os.path.isfile(path): 
     if path.endswith('.py') : 
      counter['py']+=1 
      return path, counter 
     else: 
      counter['non_py']+=1 
      return path, counter 
    elif os.path.isdir(path): 
     for files in os.listdir(path): 
      print(files) 
      path = os.path.abspath(files) 
      print(path) 
      count_file(path, counter) 
     return path, counter 

main() 

私が持っているいくつかの問題は、私は1つの再帰関数内で複数のカウンタを維持するのに苦労した

  1. です。
  2. また、私が欲しいリターンは辞書形式ですが、パスで返さなければならないので、この方法でしかできません。
  3. 私はprint(files)を使用して機能が正常に機能しているかどうかを確認しますが、私のフォルダには一度も見たことのないファイルが多く表示されます(上位7ファイル)。 print(files)

    /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 
    
    /Users/ziyuanhan/PycharmProjects/lab7/recursive_dir_traversal.py 
    .DS_Store 
    /Users/ziyuanhan/PycharmProjects/lab7/.DS_Store 
    .idea 
    /Users/ziyuanhan/PycharmProjects/lab7/.idea 
    lab7.iml 
    /Users/ziyuanhan/PycharmProjects/lab7/lab7.iml 
    misc.xml 
    /Users/ziyuanhan/PycharmProjects/lab7/misc.xml 
    modules.xml 
    /Users/ziyuanhan/PycharmProjects/lab7/modules.xml 
    workspace.xml 
    /Users/ziyuanhan/PycharmProjects/lab7/workspace.xml 
    km_mi_table.py 
    /Users/ziyuanhan/PycharmProjects/lab7/km_mi_table.py 
    km_to_miles.py 
    /Users/ziyuanhan/PycharmProjects/lab7/km_to_miles.py 
    wordfrequency.py 
    /Users/ziyuanhan/PycharmProjects/lab7/wordfrequency.py 
    ('/Users/ziyuanhan/PycharmProjects/lab7/wordfrequency.py', {'non_py': 0, 'py': 0}) 
    

    がところで私たちは再帰関数を使用する必要が

教授は、要求されたとして、それが必須です。

+0

いつこの機能を停止するのがわかりますか? –

+0

私が提供したパスのすべてのファイルとディレクトリを実行したときに停止します – Byron

+0

「停止」という意味を理解できません。 – Byron

答えて

1

あなたはディレクトリを再帰的に繰り返す必要はありません。

発信者のローカル変数/引数を変更することはできません。返信はどうですか?total_pythontotal_non_python、以下のような呼び出し元で使用しますか?

def count_file(path): 
    total_python, total_non_python = 0, 0 
    for parent, directories, files in os.walk(path): 
     for filename in files: 
      if filename.lower().endswith('.py'): 
       total_python += 1 
      else: 
       total_non_python += 1 
    return total_python, total_non_python 

def main(): 
    path = input('Enter a path to a file or directory: ') 
    total_python, total_non_python = count_file(path) 
    print(path, total_python, total_non_python) 

あるいは、os.scandirは、Python 3.5以降も使用可能です。

+1

ありがとうございます、os.walkはタスクを簡単にしますが、私たちの専門家は再帰関数を使用するように強制します – Byron

+0

@Byron、これは宿題を意味しますか? – falsetru

+0

だから、関数は基本ケースと再帰的ケースを持たなければならない – Byron

1

関数の引数としてディクショナリを渡し、ディクショナリ内の項目の値を変更することができます。

まず辞書をintialize:

counters = {'py': 0, 'other': 0} 

そして、再帰関数内でそれを変更:辞書はmutableあるため

counters['py'] += 1 

は、これは動作します。

+0

ありがとう!ディクショナリカウンタは機能しますが、ディレクトリへのパスを入力するとカウンタが0,0を返す理由はわかりません。どうぞご覧ください。 – Byron

+0

何を見てみましょうか?あなたのコードはどこですか? – stenci

+0

こんにちは申し訳ありませんが私の質問を更新することを忘れました、それは今問題です、私はあなたの提案に従っていくつかのコードを変更しました。ディレクトリへの入力パスには複数のファイルがありますが、出力はまだ(0,0) – Byron

0

この関数はパス名をとり、(total_python, total_not_python)を返します。ディレクトリ内の各エントリに対して自身を呼び出します。これは、与えられたコードに近いほど合理的であることを意図しています。

def count_file(path): 
    if os.path.isfile(path): 
     if path.endswith('.py') : 
      return 1, 0 
     else: 
      return 0, 1 
    elif os.path.isdir(path): 
     total_python, total_not_python = 0, 0 
     for files in os.listdir(path): 
      print(files) 
      path = os.path.join(path, files) 
      subtotal_python, subtotal_python = count_file(path) 
      total_python += subtotal_python 
      total_not_python += subtotal_not_python 
     return total_python, total_not_python 
+0

ありがとう!しかし、私がディレクトリへのパスを入力すると、なぜカウンタが私に0,0を与え続けているのかわかりません。 – Byron

関連する問題