web-dev-qa-db-ja.com

reverse()または[::-1]を使用せずに文字列を反転しますか?

文字列を入力として受け取り、逆の順序で返す関数を必要とする奇妙なCodecademyの演習に出会いました。唯一の問題は、スタックオーバーフロー[::-1]で、逆の方法または一般的な答えを使用できなかったことです。

プログラミングの現実の世界では、明らかに、 拡張スライス メソッドを使用するか、reversed関数を使用しますが、これが機能しない場合がありますか?

将来の人々に役立つ場合に備えて、Q&Aスタイルで以下のソリューションを紹介します。

39
samrap

また、再帰でそれを行うことができます:

def reverse(text):
    if len(text) <= 1:
        return text

    return reverse(text[1:]) + text[0]

そして、文字列helloの簡単な例:

   reverse(hello)
 = reverse(Ello) + h           # The recursive step
 = reverse(llo) + e + h
 = reverse(lo) + l + e + h
 = reverse(o) + l + l + e + h  # Base case
 = o + l + l + e + h
 = olleh
62
Blender

ちょうど別のオプション:

from collections import deque
def reverse(iterable):
    d = deque()
    d.extendleft(iterable)
    return ''.join(d)
18
Jon Clements

編集

この質問に関する最近の活動により、私は振り返り、ジェネレーターを使用して簡単なワンライナーにソリューションを変更しました:

rev = ''.join([text[len(text) - count] for count in xrange(1,len(text)+1)])

明らかに、範囲またはxrange関数の負のステップのようないくつかのより良い答えがありますが。以下は私の元のソリューションです:


ここに私の解決策があります、私はそれを段階的に説明します

def reverse(text):

    lst = []
    count = 1

    for i in range(0,len(text)):

        lst.append(text[len(text)-count])
        count += 1

    lst = ''.join(lst)
    return lst

print reverse('hello')

まず、関数にパラメーターを渡す必要があります。この場合はtextです。

次に、lstという名前の空のリストを設定して、後で使用します。 (実際、リストが必要だとはforループに到達するまで知りませんでした。なぜそれが必要なのかすぐにわかるでしょう。)

countループに入ると、for変数が意味をなします

それでは、私たちが達成しようとしていることの基本バージョンを見てみましょう。

リストに最後の文字を追加すると、逆の順序で始まることは理にかなっています。例えば:

>>lst = []
>>Word = 'foo'
>>lst.append(Word[2])
>>print lst
['o']

ただし、順序を逆にするには、Word[1]を追加してからWord[0]を追加する必要があります。

>>lst.append(Word[2])
>>lst.append(Word[1])
>>lst.append(Word[0])
>>print lst
['o','o','f']

これは素晴らしいことです。元のWordの順序が逆になっているリストがあり、.join()を使用して文字列に戻すことができます。しかし、問題があります。これはWord fooで機能し、3文字の長さのWordでも機能します。しかし、5文字のWordはどうでしょうか?または10文字?今では動作しません。 Wordが逆の順序で返されるように、追加するインデックスを動的に変更できる方法がある場合はどうでしょうか。

Forループに入ります。

for i in range(0,len(text)):

    lst.append(text[len(text)-count])
    count += 1

まず、単にinではなくin range()を使用する必要があります。これは、Wordの文字を反復処理する必要があるが、Wordのインデックス値をプルして変更する必要があるためですオーダー。

Forループの本体の最初の部分は見慣れているはずです。その非常に似ています

>>lst.append(Word[..index..])

実際、その基本概念はまったく同じです。

>>lst.append(text[..index..])

それで、中間のすべては何をしているのですか?

まず、リストの最後の文字のインデックスを追加する必要があります。これは、Wordの長さtext、-1です。これからl(t) -1と呼びます。

>>lst.append(text[len(text)-1])

それだけで、Wordの最後の文字が常に取得され、Wordの長さに関係なく、lstに追加されます。しかし、最後の文字はl(t)-1であるため、最後から2番目の文字、l(t)-2などが必要です。 、リストに追加する文字がなくなるまで。上記のcount変数を覚えていますか?それは重宝します。 forループを使用することにより、countの値を各反復で1ずつ増やすことができます。そのため、forループがWord全体を繰り返すまで、減算する値が増加します。

>>for i in range(0,len(text)):
..        
..      lst.append(text[len(text)-count])
..      count += 1

関数の中心ができたので、これまでの内容を見てみましょう。

def reverse(text):

    lst = []
    count = 1

    for i in range(0,len(text)):

        lst.append(text[len(text)-count])
        count += 1

ほぼ完了です!今、Wordの「hello」で関数を呼び出すと、次のようなリストが表示されます。

['o'、 'l'、 'l'、 'e'、 'h']

リストは必要ありません。文字列が必要です。そのために.joinを使用できます。

def reverse(text):

    lst = []
    count = 1

    for i in range(0,len(text)):

        lst.append(text[len(text)-count])
        count += 1

    lst = ''.join(lst) # join the letters together without a space
    return lst

以上です。 reverse()でWord 'hello'を呼び出すと、次のようになります。

>>print reverse('hello')
olleh

明らかに、これは実際の状況で必要なコードよりもはるかに多くのコードです。このタスクを実行するには、反転機能または拡張スライスを使用するのが最適な方法ですが、機能しない場合があり、これが必要になる場合があります。いずれにせよ、私は興味があるだれでもそれを共有すると思いました。

他のアイデアがあれば、ぜひ聞いてみてください!

11
samrap

逆のrangeを使用:

def reverse(strs):
    for i in xrange(len(strs)-1, -1, -1):
        yield strs[i]
...         
>>> ''.join(reverse('hello'))
'olleh'

xrangeまたは-1ステップのrangeは逆の順序でアイテムを返すため、len(string)-1から-1(exclusive)に繰り返し、文字列からアイテムを1つずつフェッチする必要があります1。

>>> list(xrange(len(strs) -1, -1 , -1))
[4, 3, 2, 1, 0]  #iterate over these indexes and fetch the items from the string

一発ギャグ:

def reverse(strs):
    return ''.join([strs[i] for i in xrange(len(strs)-1, -1, -1)])
... 
>>> reverse('hello')
'olleh'
11

数日間Pythonだけをコーディングしていましたが、これはかなりクリーンなソリューションだと思います。空のリストを作成し、文字列内の各文字をループしてリストの先頭に追加し、結合リストを文字列として返します。

def reverse(text):
backwardstext = []
for letter in text:
    backwardstext.insert(0, letter)
return ''.join(backwardstext)
7
user3355359

私はこれを使用しました:

def reverse(text):
s=""
l=len(text)
for i in range(l):
    s+=text[l-1-i]
return s
5
Sumit Kushwaha

これは非常に興味深い質問です。簡単なワンライナーの回答を提供したいと思います。

>>> S='abcdefg'
>>> ''.join(item[1] for item in sorted(enumerate(S), reverse=True))
'gfedcba'

簡単な説明:

enumerate()[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g')]を返します。インデックスと値。値を逆にするには、sorted()で逆に並べ替えます。最後に、strに戻すだけです

4
CT Zhu

ジョンの答えに触発されて、これはどうですか

Word = 'hello'
q = deque(Word)
''.join(q.pop() for _ in range(len(Word)))
4
Burhan Khalid
reduce(lambda x, y : y + x, "hello world")
3
Vinod Puliyadi

リポジトリでpythonの文字列を逆にする方法の異なるバージョンを作成しました: https://github.com/fedmich/Python-Codes/tree/master/Reverse%20a%20String

それにはlist-comprehensionまたは lambda technique を使用します:

# Reverse a string without using reverse() function
s = 'Federico';
li = list( s )  #convert string to list

ret = [ li[i-1] for i in xrange(len(li),0,-1)  ]    #1 liner lambda
print ( "".join( ret ) )

または back for for loop を実行して

# Reverse a string without using reverse() function
s = 'Federico';
r = []

length = len(s)
for i in xrange(length,0,-1):
    r.append( s[ i - 1] )

print ( "".join(r) )
3
fedmich
def reverse(s):
    return "".join(s[i] for i in range(len(s)-1, -1, -1))
2
CrackSmoker9000

私はコードアカデミーでこれを解決し、自分の答えをチェックしてこのリストを見つけました。 pythonの理解が非常に限られていたので、これをやっただけでうまくいきました。

def reverse(s):
    i = len(s) - 1
    sNew = ''
    while  i >= 0:
        sNew = sNew + str(s[i])
        i = i -1
    return sNew
2
dewetha

ゴルフバージョン:r=lambda x:"".join(x[i] for i in range(len(x-1),-1,-1))

2
rlms

Blenderの答えは素晴らしいですが、非常に長い文字列の場合、RuntimeError: maximum recursion depth exceededという途方もない結果になります。 Pythonで再帰を頻繁に行う必要があるため、同じコードをwhileループにリファクタリングできます。時間とメモリの問題が原因で明らかに悪い状態ですが、少なくともエラーは発生しません。

def reverse(text):
    answer = ""
    while text:
        answer = text[0] + answer
        text = text[1:]
    return answer
2
mehtunguh

逆の文字列を実現するために行ったのは、次のようにforループ内の文字列の長さとxrange関数を使用し、後退することだけです。

myString = "ABC"

for index in xrange(len(myString),-1):
    print index

私の出力は「CBA」です

1

最後の文字から文字列を単純に逆反復することができます。 pythonを使用すると、リストの内包表記を使用して文字のリストを逆の順序で作成し、それらを結合して1行で逆の文字列を取得できます。

def reverse(s):
  return "".join([s[-i-1] for i in xrange(len(s))])

ネガティブインデックスを使用することさえ許可されていない場合は、s[-i-1]s[len(s)-i-1]に置き換える必要があります。

1

これはfor iを範囲ループで使用する私のソリューションです:

def reverse(string):
    tmp = ""
    for i in range(1,len(string)+1):
        tmp += string[len(string)-i]            
    return tmp

理解するのはとても簡単です。インデックスの範囲外を避けるために、1から始めます。

1
Stefano Saitta

また、コードアカデミーに関する対応する演習を解決し、他のアプローチと比較したいと考えました。私はこれまで使用した解決策を見つけていないので、ここにサインアップして他の人に自分の解決策を提供すると思いました。そして、コードを改善する方法についての提案や役立つコメントを受け取るかもしれません。

わかりました、文字列を保存するためにリストを使用せず、代わりに文字列インデックスにアクセスしました。最初はlen()とインデックス番号を扱うのに少し時間がかかりましたが、最終的にはうまくいきました:)。

def reverse(x):
reversestring = ""
for n in range(len(str(x))-1,-1, -1):
    reversestring += x[n]
return reversestring 

reversestring = ""をもっとエレガントな方法で解決できるのか、それとも「悪いスタイル」なのか、まだ疑問に思っていますが、これまでのところ答えが見つかりませんでした。

1
Fadeiar

リストをスタックとして使用するものは次のとおりです。

def reverse(s):
  rev = [_t for _t in s]
  t = ''
  while len(rev) != 0:
    t+=rev.pop()
  return t
1
user2399453

このように簡単にできます

def rev(str):
   rev = ""
   for i in range(0,len(str)):
   rev = rev + str[(len(str)-1)-i]
   return rev
1
Vijay
def reverseThatString(theString):
    reversedString = ""
    lenOfString = len(theString)
    for i,j in enumerate(theString):
        lenOfString -= 1
        reversedString += theString[lenOfString]
    return reversedString
1
mattshirtliffe

これは、whileループでそれを行う方法です。

def reverse(s):
    t = -1
    s2 = ''
    while abs(t) < len(s) + 1: 
        s2 = s2 + s[t]
        t  = t - 1
    return s2
1
PythonSam
def reverse(text):
    a=""
    l=len(text)
    while(l>=1):
        a+=text[l-1]
        l-=1
    return a

文字列aにテキストの最も高いインデックスを連結しました(ループごとに1ずつ減り続けます)。

1

今日、私はペンと紙でこれと同じエクササイズを求められたので、リストのためにこの機能を思いつきました:

def rev(s):
  l = len(s)
  for i,j in Zip(range(l-1, 0, -1), range(l//2)):
    s[i], s[j] = s[j], s[i]
  return s

"".join(rev(list("hello")))の文字列で使用できます

1
berdario

これが私の貢献です。

def rev(test):  
    test = list(test)
    i = len(test)-1
    result = []

    print test
    while i >= 0:
        result.append(test.pop(i))
        i -= 1
    return "".join(result)
1
fra

多くの代替の回答を受け取りましたが、別の簡単な解決策を追加するだけです。最初に考えたのは次のようなものです。

def reverse(text):
    reversed_text = ""   

    for n in range(len(text)):
        reversed_text += text[-1 - n]

    return reversed_text

人々が言及した(または組み込みのメソッド)他のオプションほど高速ではありませんが、text文字列の長さを使用してスライスすることで一度に1文字ずつ連結するだけなので、簡単に理解できます。正面に向かって終わり。

1
PerryAJ

提案されているように、単にポップを使用できます。そのためのライナーが1つあります

chaine = 'qwertyuiop'
''.join([chaine[-(x + 1)] for x in range(len(chaine))])
'poiuytrewq'
gg = list(chaine)
''.join([gg.pop() for _ in range(len(gg))])
'poiuytrewq'
0
cgte

私の解決策:

s = raw_input( "文字列を入力")
印刷
def reverse(text):

st = ""  
rev = ""  
count = len(text)  
print "Lenght of text: ", len(text)  
print  
for c in range(len(text)):  
    count = count - 1  
    st = st + "".join(text[c])  
    rev = rev + "".join(text[count])  
    print "count:       ", count  
    print "print c:     ", c  
    print "text[c]:     ", text[c]  
    print  
print "Original:    ", st  
print "Reversed:    ", rev  
return rev  

逆転

結果画面

文字列jocaを入力

テキストの長さ:4

カウント:3
print c:0
text [c]:j

カウント:2
print c:1
text [c]:o

カウント:1
print c:2
text [c]:c

カウント:0
print c:3
text [c]:a

オリジナル:joca
反転:acoj
無し

0
Jovica

組み込み関数を使用せずに考えられる方法:

a = 'Word'
count = 0
for letter in a:
    count += 1

b = ''
for letter in a:
    b += a[count-1]
    count -= 1

そして、bを印刷すると:

print b
drow
0
Sunny Mui

これは、python 2.7構文で最も簡単な方法です

def reverse(text):

      rev = ""
      final = ""

      for a in range(0,len(text)):
            rev = text[len(text)-a-1]
            final = final + rev
return final
0
AceRam

あまり賢くないが、トリッキーなソリューション

def reverse(t):
    for j in range(len(t) // 2):
        t = t[:j] + t[- j - 1] + t[j + 1:- j - 1] + t[j] + t[len(t) - j:]
    return t
0
Dmitry_Kovalov

私はこれをforループを使用して文字列を反転させる最良の方法として好んでいます。

def reverse_a_string(str): 

    result=" "
    for i in range(len(str),1,-1):
        result= result+ str[i-1]
    return result

print reverse_a_string(input())
0
Kapilfreeman
enterString=input("Enter a string to be reversed:")
string_List=list(enterString)
revedString=[]

for i in range(len(string_List)):
    revedString.append(string_List.pop())
#Pop last element and append it to the empty list
print "reversed string is:",''.join(revedString)
#as the out come is in list convert it into string using .join

Sample Output:
>>>Enter a string to be reversed :sampleReverse1  
>>>reversed string is:1esreveRelpmas 
0
Sanyal

単純にこれを実行しますが、2番目のバージョンでは1文字で各文字を印刷します。

def rev(str):
        for i in range(0,len(str)):
            print(list(str)[len(str)-i-1])

1行で印刷します。

def rev(str):
    rev = list()
    for i in range(0,len(str)):
        rev.append((list(str)[len(str)-i-1]))
    print(''.join(rev))
0
jax

ポイントフリー:

from functools import partial
from operator import add

flip = lambda f: lambda x, y: f(y, x)
rev = partial(reduce, flip(add))

テスト:

>>> rev('hello')
'olleh'
0
pillmuncher
m = input("Enter string::")
def rev(s):
    z = -1
    x = len(s)
    while x != 0:
        print(s[z], end='')
        z = z-1
        x = x-1
rev(m)
0
chandra

十分な答えがあります。

別の方法で共有したいだけです。

あなたは逆の2つの小さな関数を書いて、関数の出力を与えられた文字列と比較することができます

var = ''

def reverse(data):

for i in data:
    var = i + var
return var

var == dataでない場合:

印刷物「パリンドロームなし」

その他:

「パリンドローム」を印刷

0
rajpython

簡単な方法、

>>> a = "hi hello"
>>> ''.join([a[len(a)-i-1] for i,j in enumerate(a)])
'olleh ih'
>>>