4

forこれを定式化するためにループを使用しようとしています:

  • expand('*+123456')戻るべき'1*2+3*4+5*6'

  • expand('++123')戻るべき'1+2+3'

  • expand('+*1234')戻るべき'1+2*3+4'

記号は、指定された文字列の最初の 2 文字から交互に選択され、先行する数字の間に配置されます。

これが私が取り組んできたものです:

def expand(original):
    var = ""
    symbols = original[0:2]
    for i in range(len(original)):
        var = var + symbols + original[i]
    return var

もあるに違いないことoriginal[2:]はわかっていますが、これをここのどこに当てはめることができるかわかりません。

私はアマチュアで、長い間この問題を理解しようとしてきました。

4

5 に答える 5

4

はい、[2:]そこに追加することで機能が改善されますが、range(len(original)). 書いていることに気づいたときはいつでもrange(len(something))、一歩下がって、実際に何をしようとしているのかを考えるべきです。

この場合、文字列内の文字を探しており、 を使用するとより簡単に取得できますfor x in string。これらのアイデアを考慮して、わずかに改善されたバージョンを次に示します。

def expand(original):
    var = ""
    symbols = original[:2]
    for digit in original[2:]:
        var += (digit + symbols)
    return var

これにより、出力の最初に奇妙な記号が混在するのを防ぐことができますが、それでも完全ではありません。

>>> expand('+*1234')
'1+*2+*3+*4+*'

私たちは方法を見つける必要があります

  1. シンボルを交互に取り、
  2. 文字列の最後からそれらを残します。

itertools.cycleを使用してこれらの最初のものを処理し、2 番目の文字列スライスを処理できます。

from itertools import cycle

def expand(original):
    var = ""
    symbols = cycle(original[:2])
    for digit in original[2:]:
        var += (digit + next(symbols))
    return var[:-1]

それは機能しますが、ある時点で、効率が悪いため、文字列を使用し+たり作成したりするべきではないと誰かがパイプで言います。+=代わりにリストを作成し、それを使用str.join()して文字列に変換すると、少し改善できます。

from itertools import cycle

def expand(original):
    chars = []
    symbols = cycle(original[:2])
    for digit in original[2:]:
        chars.extend([digit, next(symbols)])
    return "".join(chars[:-1])

しかし、私たちはそれ以上のことをすることができます。next(symbols)毎回呼び出す必要はなく、一度zip()に次のシンボルと次の数字のペアを取得するために使用できます。

from itertools import cycle

def expand(original):
    chars = []
    for symbol, digit in zip(cycle(original[:2]), original[2:]):
        chars.extend([digit, symbol])
    return "".join(chars[:-1])

...そしておそらくそれで十分です:-)

編集:別の回答へのコメントで、標準ライブラリから何もインポートできないと言ったので(かなりばかげた制限IMOですが、そこにあります)、cycle()リンクで説明されているPython実装を使用できますこの回答の前半:

def cycle(iterable):
    # cycle('ABCD') --> A B C D A B C D A B C D ...
    saved = []
    for element in iterable:
        yield element
        saved.append(element)
    while saved:
        for element in saved:
            yield element

...しかし、おそらく、 yieldキーワードを理解する必要があることを意味し、それを理解していることを先生に納得させる準備をしておく必要があります。

于 2012-11-01T01:24:33.677 に答える
3

これに沿って何かを試すことができます:

a = "*+123456"

def expand(input):
    symbols = input[:2]
    numbers = input[2:]

    result = ""
    for count, number in enumerate(numbers):
        # Switch symbol for every other iteration
        result += number + symbols[count%2]

    # There's an extra symbol at the end, so remove it.
    return result[:-1]

インタープリターでのサンプル実行は次のとおりです。

>>> a = "*+123456"
>>> def expand(input):
...     symbols = input[:2]
...     numbers = input[2:]
...     result = ""
...     for count, number in enumerate(numbers):
...         result += number + symbols[count%2]
...     return result[:-1]
... 
>>> expand(a)
'1*2+3*4+5*6'
>>> a = "++123456"
>>> expand(a)
'1+2+3+4+5+6'

コードで注意すべき点:

enumerate- 反復可能なオブジェクトを受け取り、形式でタプルを返します(index, value)

input[:2]- 文字配列の先頭から位置 2 の要素までのスライスを取得します (包括的ではありません)。

input[2:]- 文字配列の位置 2 から最後まで (両端を含む) のスライスを取得します。

list[:-1]- リストの先頭からリストの末尾の 1 要素までスライスします。

count%2- 配列内の文字のカウント (インデックス) を取り、それを 2 で割り、剰余を維持します。この結果は、2 つのシンボルを切り替えるたびに 0 と 1 の間で変化します。

于 2012-11-01T00:57:35.410 に答える
2

を使用itertoolsして、演算子記号を「循環」し、それらを数値でインターリーブ (「zip」) できます。

import itertools

def expand(original):
    var = ""
    symbols = original[:2]
    numbers = original[2:]
    for symbol, number in zip(numbers[:-1], itertools.cycle(symbols)):
        var += symbol + number
    return var + numbers[-1]

これは以下を出力します:

>>>展開('*+123456')
'1*2+3*4+5*6'
>>>展開('++123')
「1+2+3」
>>>展開('+*1234')
'1+2*3+4'
于 2012-11-01T01:04:10.707 に答える
1

遅い答え、ここのすべてがより便利ですが、何らかの理由でこれは私の興味をそそりました:

In [9]: from itertools import izip, cycle

In [10]: def expand(s):
   ....:   return ''.join(reduce(lambda x, y: x+y, izip(s[2:], cycle(s[:2]))))[:-1]
   ....:

In [11]: expand('*-123')
Out[11]: '1*2-3'

In [12]: expand('+-123456')
Out[12]: '1+2-3+4-5+6'

私は@Bitwiseらが言ったことに完全に同意します-それはあなたの制約に合わないので、あなたが求めているものではないので、ストリームを乱雑にして申し訳ありません:)

後世のために、これは問題の文字列を取得し、reduce関数を使用して数字を交互の記号文字列の 1 つとペアにします。次に、最後のシンボルをトリムして、join'ed' の結果を返します。これは文字列になります。うまくいけば、これは将来役に立つでしょう!

于 2012-11-01T01:34:47.383 に答える
1

必要に応じて FOR ループを使用する 1 つのオプションを次に示します。

def expand(x):

    p=x[:2]
    n=x[2:]
    s=''
    c=0

    for i in n:
       s+=i
       s+=p[c]
       c=1-c

    return s[:-1]

アイデアは、文字列を演算子文字列pと数値文字列nに分離し、両方を反復処理することです。c変数は 0 から 1 へ、またその逆に変化するため、常に p を反復処理します(モジュロでも同じことができます)。これを行うためのより「pythonic」な方法については、他の回答を参照してください(私はアマチュアの明快さを求めていました)。

于 2012-11-01T01:01:55.867 に答える