回答:
このためのreversed
関数を次のように使用できます。
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
reversed(...)
はリストを返さないことに注意してください。を使用して、逆のリストを取得できますlist(reversed(array))
。
reverse
ただし、後でリストにキャストする必要がない場合は、より高速になることがあります。
reversed()
スライスの代わりに使うのですか?Zen of Pythonを読んでください、ルール番号7:読みやすさが重要です!
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
拡張スライス構文は、Python What's new Entry for releaseで詳しく説明されています2.3.5
コメント内の特別な要求により、これは最新のスライスドキュメントです。
reversed
返します。listreverseiterator
次に、それを反復する必要があります。-逆スライシングは、逆にしたリスト/タプル/文字列を返します(何をスライスするかによって異なります)。@Einar Petersenが文字列を反転しているため、出力は正しいです。試してみる:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]
または
>>> L[::-1]
[40, 20, 10, 0]
L=L[::-1]
、実際にリストを逆にすることです。そうしないと、値を逆に返すだけです
b = l[-n:] b.reverse() l = b + l[:len(l) - n]
array = array [::-1]のようにスライスを使用することは、きちんとしたトリックで非常にPython的ですが、初心者には少しあいまいです。reverse()メソッドを使用すると、簡単に読み取ることができるため、日々のコーディングを行うのに適した方法です。
ただし、インタビューの質問のようにリストを元に戻す必要がある場合は、これらのような組み込みのメソッドを使用できない可能性があります。インタビュアーは、Pythonの知識の深さではなく、問題へのアプローチ方法を検討します。アルゴリズムによるアプローチが必要です。次の例では、クラシックスワップを使用していますが、その方法の1つかもしれません。
def reverse_in_place(lst): # Declare a function
size = len(lst) # Get the length of the sequence
hiindex = size - 1
its = size/2 # Number of iterations required
for i in xrange(0, its): # i is the low index pointer
temp = lst[hiindex] # Perform a classic swap
lst[hiindex] = lst[i]
lst[i] = temp
hiindex -= 1 # Decrement the high index pointer
print "Done!"
# Now test it!!
array = [2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]
print array # Print the original sequence
reverse_in_place(array) # Call the function passing the list
print array # Print reversed list
**The result:**
[2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]
Done!
[654, 124, 24, 7, 1, 65, 60, 32, 27, 25, 19, 12, 9, 8, 5, 2]
これはタプルまたは文字列シーケンスでは機能しないことに注意してください。これは、文字列とタプルは不変であるため、要素に変更を加えるためにそれらに書き込むことができないためです。
lst[hiindex], lst[i] = lst[i], lst[hiindex]
、を介して行うことができると思います... ;-)
array[::-1]
、完全に読み取り可能で完全に明示的です。「読み取り可能」とは、「Pythonスライスを使用したことがない人でも、読み取り可能である必要がある」という意味ではありません。[::-1]
反転スライスはPythonで途方もなく、共通のイディオム(既存のコード内のすべての時間をそれに遭遇するだろう)であり、それは完全に読みやすいです、あなたが定期的にPythonのを使用している場合。確かに、first10 = []
、for i in range(10): first10.append(array[i])
明確かつ明示的であるが、それはそれがより良いよりも作成しませんfirst10 = array[:10]
。
他のいくつかの提案とl.reverse()
は異なり、Python 3および2で長いリストを逆にする最も速い方法であることがわかりました。他の人がこれらのタイミングを複製できるかどうか知りたいです。
l[::-1]
リストを元に戻す前にコピーするため、おそらく遅くなります。list()
によって作成されたイテレータの周りに呼び出しを追加すると、reversed(l)
オーバーヘッドが追加されます。もちろん、リストまたはイテレータのコピーが必要な場合は、それぞれのメソッドを使用しますが、リストを逆にするだけの場合はl.reverse()
、最速の方法のようです。
機能
def rev_list1(l):
return l[::-1]
def rev_list2(l):
return list(reversed(l))
def rev_list3(l):
l.reverse()
return l
リスト
l = list(range(1000000))
Python 3.5のタイミング
timeit(lambda: rev_list1(l), number=1000)
# 6.48
timeit(lambda: rev_list2(l), number=1000)
# 7.13
timeit(lambda: rev_list3(l), number=1000)
# 0.44
Python 2.7のタイミング
timeit(lambda: rev_list1(l), number=1000)
# 6.76
timeit(lambda: rev_list2(l), number=1000)
# 9.18
timeit(lambda: rev_list3(l), number=1000)
# 0.46
list.reverse
それはその場で逆転するので、最も速いです
list.reverse()
最速ですが、あなたが不利にしているreversed
(あなたが最良の時に使用されていない新しいが欲しいlist
だけ反復既存に、list
オリジナルを変異させずに逆の順序で)、そしてまた元に変異を回避スライス(list
、通常reversed
、入力が小さい場合よりも高速です)。はい、コピーが必要ない場合、コピーするものはより高価ですが、多くの場合、元の値を変更したくありません。
reversed
それでもまだ負けているlist.reverse()
ように見えますが、入力が変化しないことを考えるとlist
、多くの場合それはより優れています。の損失reversed
はわずかです(の約1/6ですlist.reverse()
)。
for x in array[::-1]:
do stuff
reversed(array)を使用するのがおそらく最良の方法です。
>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>> print item
組み込みのを使用せずにこれを実装する方法を理解する必要がある場合reversed
。
def reverse(a):
midpoint = len(a)/2
for item in a[:midpoint]:
otherside = (len(a) - a.index(item)) - 1
temp = a[otherside]
a[otherside] = a[a.index(item)]
a[a.index(item)] = temp
return a
これにはO(N)時間かかるはずです。
いくつかの良い答えがありますが、広がっており、ほとんどが各アプローチの根本的な違いを示していません。
全体として、組み込み関数/組み込みメソッドを使用して、ほぼすべての関数と同様に、リバースすることをお勧めします。この場合、手動で作成したインデックス付けの方法と比較して、短いリスト(10アイテム)では約2〜8倍、長いリストでは最大300倍以上高速になります。これは、専門家がそれらを作成し、精査し、最適化するため、理にかなっています。また、欠陥が発生しにくく、エッジおよびコーナーのケースを処理する可能性が高くなります。
また、次のことを行うかどうかも検討してください。
object.reverse()
方法ですreversed(object)
イテレータを作成することですobject[::-1]
ここでは、対象となるメソッドのテストスクリプトの開始点を示します。この回答にすべてのコードスニペットをまとめて、リストを逆にしてそれぞれの時間を逆にするさまざまな方法をすべて実行するスクリプトを作成します(出力は前のセクションに表示されています)。
from timeit import timeit
from copy import copy
def time_str_ms(t):
return '{0:8.2f} ms'.format(t * 1000)
目的が既存のリストの項目の順序を逆にすることであり、それらをループしたり、コピーを処理したりすることなく、場合は、 <list>.reverse()
関数をます。これをリストオブジェクトで直接実行すると、すべてのアイテムの順序が逆になります。
以下は、指定された元の変数を逆にしますが、逆のリストも返します。つまり、この関数出力を使用してコピーを作成できます。通常、このための関数は作成しませんが、最後にタイミングコードを使用するために作成しました。
この2つの方法のパフォーマンスをテストします。まず、リストを元の場所に戻す(元のリストを変更する)だけです。次に、リストをコピーして後で元に戻します。
def rev_in_place(mylist):
mylist.reverse()
return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()
return a
obj[::-1]
組み込みのインデックススライシングメソッドを使用すると、インデックス付きオブジェクトの一部のコピーを作成できます。
一般的な構文は次のとおりです<object>[first_index:last_index:step]
。スライスを利用して単純な逆リストを作成するには、次のコマンドを使用します。<list>[::-1]
。オプションを空のままにすると、オブジェクトの最初と最後の要素のデフォルトに設定されます(ステップサイズが負の場合は逆になります)。
インデックスを作成すると、オブジェクトのインデックスの末尾から逆方向に数える負の数を使用できます(つまり、-2は最後から2番目のアイテムです)。ステップサイズが負の場合、最後の項目から開始し、その量だけ後方にインデックスを付けます。これに関連して、最適化されたいくつかの開始-終了ロジックがあります。
def rev_slice(mylist):
a = mylist[::-1]
return a
reversed(obj)
反復関数を使用してリストを逆にするreversed(indexed_object)
関数があります:
未加工のイテレータと、イテレータからリストを作成することの両方でテストします。
def reversed_iterator(mylist):
a = reversed(mylist)
return a
def reversed_with_list(mylist):
a = list(reversed(mylist))
return a
タイミングがわかるように、独自のインデックス作成方法を作成することは悪い考えです。本当にカスタムなことをする必要がない限り、組み込みのメソッドを使用してください。
とはいえ、リストのサイズが小さくても大きなペナルティはありませんが、スケールアップするとペナルティが途方もなく大きくなります。以下のコードは最適化できると確信していますが、組み込みメソッドを使用します。
def rev_manual_pos_gen(mylist):
max_index = len(mylist) - 1
return [ mylist[max_index - index] for index in range(len(mylist)) ]
def rev_manual_neg_gen(mylist):
## index is 0 to 9, but we need -1 to -10
return [ mylist[-index-1] for index in range(len(mylist)) ]
def rev_manual_index_loop(mylist):
a = []
reverse_index = len(mylist) - 1
for index in range(len(mylist)):
a.append(mylist[reverse_index - index])
return a
def rev_manual_loop(mylist):
a = []
reverse_index = len(mylist)
for index, _ in enumerate(mylist):
reverse_index -= 1
a.append(mylist[reverse_index])
return a
以下は、リバースの各方法の時間を計る残りのスクリプトです。スライスを使用することがコピーを作成する最も速い方法である一方でobj.reverse()
、reversed(obj)
イテレータを使用してその場で反転し、イテレータを作成することが常に最速であることを示しています。
また、必要がない限り、自分でそれを行う方法を作成しようとしないことも証明されています。
loops_to_test = 100000
number_of_items = 10
list_to_reverse = list(range(number_of_items))
if number_of_items < 15:
print("a: {}".format(list_to_reverse))
print('Loops: {:,}'.format(loops_to_test))
# List of the functions we want to test with the timer, in print order
fcns = [rev_in_place, reversed_iterator, rev_slice, rev_copy_reverse,
reversed_with_list, rev_manual_pos_gen, rev_manual_neg_gen,
rev_manual_index_loop, rev_manual_loop]
max_name_string = max([ len(fcn.__name__) for fcn in fcns ])
for fcn in fcns:
a = copy(list_to_reverse) # copy to start fresh each loop
out_str = ' | out = {}'.format(fcn(a)) if number_of_items < 15 else ''
# Time in ms for the given # of loops on this fcn
time_str = time_str_ms(timeit(lambda: fcn(a), number=loops_to_test))
# Get the output string for this function
fcn_str = '{}(a):'.format(fcn.__name__)
# Add the correct string length to accommodate the maximum fcn name
format_str = '{{fx:{}s}} {{time}}{{rev}}'.format(max_name_string + 4)
print(format_str.format(fx=fcn_str, time=time_str, rev=out_str))
結果は、スケーリングが、特定のタスクに最も適した組み込みメソッドで最適に機能することを示しています。つまり、オブジェクト要素の数が増えると、組み込みメソッドのパフォーマンス結果がはるかに優れたものになります。
また、物事をひもでつなぐよりも、必要なものを直接実現する最良の組み込みメソッドを使用する方が得策です。つまり、反転したリストのコピーが必要な場合はスライスが最適です。reversed()
関数からリストを作成するよりも速く、リストのコピーを作成してインプレースを実行するよりも高速ですobj.reverse()
。しかし、これらの方法のいずれかが本当に必要なすべての場合、より高速ですが、速度が2倍を超えることはありません。一方、カスタムの手動による方法は、特に非常に大きなリストの場合、桁違いに長くかかることがあります。
1000項目のリストを使用したスケーリングの場合、reversed(<list>)
関数呼び出しはイテレータのセットアップに最大30ミリ秒かかります。インプレースの反転は約55ミリ秒かかります。sliceメソッドを使用すると、完全な反転リストのコピーを作成するのに最大210ミリ秒かかりますが、私が作った最速の手動の方法は〜8400 msかかりました!!
リストに2つのアイテムがある場合:
a: [0, 1]
Loops: 100,000
rev_in_place(a): 24.70 ms | out = [1, 0]
reversed_iterator(a): 30.48 ms | out = <list_reverseiterator object at 0x0000020242580408>
rev_slice(a): 31.65 ms | out = [1, 0]
rev_copy_reverse(a): 63.42 ms | out = [1, 0]
reversed_with_list(a): 48.65 ms | out = [1, 0]
rev_manual_pos_gen(a): 98.94 ms | out = [1, 0]
rev_manual_neg_gen(a): 88.11 ms | out = [1, 0]
rev_manual_index_loop(a): 87.23 ms | out = [1, 0]
rev_manual_loop(a): 79.24 ms | out = [1, 0]
リストに10項目あります。
rev_in_place(a): 23.39 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_iterator(a): 30.23 ms | out = <list_reverseiterator object at 0x00000290A3CB0388>
rev_slice(a): 36.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_copy_reverse(a): 64.67 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_with_list(a): 50.77 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_pos_gen(a): 162.83 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_neg_gen(a): 167.43 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_index_loop(a): 152.04 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_loop(a): 183.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
リストに1000項目あります:
rev_in_place(a): 56.37 ms
reversed_iterator(a): 30.47 ms
rev_slice(a): 211.42 ms
rev_copy_reverse(a): 295.74 ms
reversed_with_list(a): 418.45 ms
rev_manual_pos_gen(a): 8410.01 ms
rev_manual_neg_gen(a): 11054.84 ms
rev_manual_index_loop(a): 10543.11 ms
rev_manual_loop(a): 15472.66 ms
反転リストの要素を他の変数に格納する場合は、revArray = array[::-1]
またはを使用できますrevArray = list(reversed(array))
。
ただし、最初のバリアントは少し高速です。
z = range(1000000)
startTimeTic = time.time()
y = z[::-1]
print("Time: %s s" % (time.time() - startTimeTic))
f = range(1000000)
startTimeTic = time.time()
g = list(reversed(f))
print("Time: %s s" % (time.time() - startTimeTic))
出力:
Time: 0.00489711761475 s
Time: 0.00609302520752 s
timeit
。
Pythonでは、リストの順序もsortで操作でき、変数を数値/アルファベット順に整理します。
print(sorted(my_list))
my_list.sort(), print(my_list)
フラグ「reverse = True」でソートできます。
print(sorted(my_list, reverse=True))
または
my_list.sort(reverse=True), print(my_list)
値を並べ替えるのではなく、値を逆にするだけかもしれません。次に、次のようにします。
print(list(reversed(my_list)))
** 番号はアルファベット順でリスト順に優先されます。Pythonの値の構成は素晴らしいです。
いくつかの古い学校のロジックを使用して、インタビューの練習をします。
数字を前から後ろに入れ替えます。2つのポインターの使用
index[0] and index[last]
def reverse(array):
n = array
first = 0
last = len(array) - 1
while first < last:
holder = n[first]
n[first] = n[last]
n[last] = holder
first += 1
last -= 1
return n
input -> [-1 ,1, 2, 3, 4, 5, 6]
output -> [6, 1, 2, 3, 4, 5, -1]
別の解決策は、これにnumpy.flipを使用することです
import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]
厳密に言えば、問題はリストを逆に返す方法ではなく、リスト名の例を使用してリストを逆にする方法array
です。
名前付きリスト逆にするには"array"
、使用しますarray.reverse()
。
説明されている非常に便利なスライスメソッドは、を使用してリストをそれ自体のスライスされた変更として定義することにより、リストを元に戻すために使用することもできarray = array[::-1]
ます。
array[:] = array[::-1]
インタビュー機能の設定であると仮定して、組み込み関数の最小量
array = [1, 2, 3, 4, 5, 6,7, 8]
inverse = [] #create container for inverse array
length = len(array) #to iterate later, returns 8
counter = length - 1 #because the 8th element is on position 7 (as python starts from 0)
for i in range(length):
inverse.append(array[counter])
counter -= 1
print(inverse)
def reverse(my_list):
L = len(my_list)
for i in range(L/2):
my_list[i], my_list[L-i - 1] = my_list[L-i-1], my_list[i]
return my_list
//
フロアディビジョンオペレーターの方が適しています。