12

OK、私はPython 2.7.3を使用しています。これが私のコードです:

def lenRecur(s): 

    count = 0

    def isChar(c):
        c = c.lower()
        ans=''
        for s in c:
            if s in 'abcdefghijklmnopqrstuvwxyz':
                ans += s
        return ans

    def leng(s):
        global count
        if len(s)==0:
            return count
        else:
            count += 1
            return leng(s[1:])

    return leng(isChar(s))

count関数内の変数を変更しようとしていlengます。私が試したことは次のとおりです。

  1. 変数カウントをlenRecur関数の外に置くと、最初は正常に動作しますが、Python シェルを再起動せずに再試行すると、カウントは (明らかに) 再起動しないため、追加し続けます。
  2. count += 1行を変更しcount = 1ても機能しますが、出力は(明らかに)1つです。

ここでの私の目標は、再帰を使用して文字列の長さを取得することですが、文字数を追跡する方法がわかりません。グローバル変数に関する情報を検索しましたが、まだ行き詰まっています。まだ理解していないのか、コードに問題があるのか​​ わかりません。

前もって感謝します!

4

6 に答える 6

28

countinlenRecurはグローバルではありません。これはスコープ変数です。

この方法で動作させるには、Python 3 を使用する必要があります。Python 3 に追加されたnonlocalステートメントを探しています。

countPython 2 では、代わりにミュータブル (リストなど) を使用することで、この制限を回避できます。

def lenRecur(s): 

    count = [0]

    # ...

    def leng(s):
        if len(s)==0:
            return count[0]
        else:
            count[0] += 1
            return lenIter(s[1:])

count名前自体を変更する必要はなくなりました。変更されず、同じリストを参照し続けます。リストに含まれる最初の要素を変更するだけですcount

別の「スペル」はcount、関数属性を作成することです。

def lenRecur(s): 

    # ...

    def leng(s):
        if len(s)==0:
            return leng.count
        else:
            leng.count += 1
            return lenIter(s[1:])

    leng.count = 0

countローカルではなくなりましたlenRecur()lenRecur()代わりに不変関数の属性になりました。

あなたの特定の問題について、あなたは実際に物事を考えすぎています。再帰に合計をさせるだけです:

def lenRecur(s):
    def characters_only(s):
        return ''.join([c for c in s if c.isalpha()])

    def len_recursive(s):
        if not s:
            return 0
        return 1 + len_recursive(s[1:])

    return len_recursive(characters_only(s))

デモ:

>>> def lenRecur(s):
...     def characters_only(s):
...         return ''.join([c for c in s if c.isalpha()])
...     def len_recursive(s):
...         if not s:
...             return 0
...         return 1 + len_recursive(s[1:])
...     return len_recursive(characters_only(s))
... 
>>> lenRecur('The Quick Brown Fox')
16
于 2013-06-27T11:35:58.847 に答える
3

変数を次のような関数変数にする必要があります

def lenRecur(s):
    lenRecur.count = 0

ただし、コードにいくつかの問題があります。

1) 再帰によって文字列内のアルファベットの数を見つけようとしている場合は、次のようになります。

def lenRecur(s):
    def leng(s, count = 0):
            if not s:
                    return count
            else:
                    count += int(s[0].isalpha())
                    return leng(s[1:], count)
    return leng(s)

しかし、leng メソッドがまったくないように、タスクを実行するために単一の関数を使用することをお勧めします。

2)あなたの目標が文字列内のアルファベットの数を見つけることだけであれば、リスト内包表記を好むでしょう

def alphalen(s):
    return sum([1 for ch in s if ch.isalpha()])

これが学習目的以外の場合は、再帰を避けることをお勧めします。なぜなら、ソリューションはより大きな文字列には使用できないためです(たとえば、ファイルの内容からアルファベットの数を見つけるなど)。Maximum Recursion Depth Exceeded の RunTimeError にヒットする可能性があります。

setrecursionlimit 関数を使用して再帰の深さを設定することでこれを回避できますが、他の簡単な方法を使用することをお勧めします。recursionlimit の設定の詳細については、こちらを参照してください。

于 2013-06-27T12:22:52.530 に答える
1

グローバル変数として使用する場合は、すべての関数定義の外で定義します。

count = 0
def lenRecur(s): 

またはそれを関数属性として定義します。

def lenRecur(s): 
    lenRecur.count = 0
    def isChar(c):

nonlocalこれは、次のステートメントを使用できる py3.x で修正されています。

def leng(s):
    nonlocal count
    if len(s)==0:
于 2013-06-27T11:37:41.403 に答える
0

カウントは必要ありません。以下の機能が動作するはずです。


    def leng(s):
        if not s:
            return 0
        return 1 + leng(s[1:])

于 2013-06-27T11:42:09.167 に答える