これで、繰り返しループ中にリストを変更するのは安全ではないことがわかりました。ただし、文字列のリストがあり、文字列自体を削除したいとします。変更可能な値の置換は変更としてカウントされますか?
これで、繰り返しループ中にリストを変更するのは安全ではないことがわかりました。ただし、文字列のリストがあり、文字列自体を削除したいとします。変更可能な値の置換は変更としてカウントされますか?
回答:
それは貧弱な形態と考えられています。代わりにリスト内包表記を使用してください。リストへの既存の参照を保持する必要がある場合は、スライス割り当てを使用してください。
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
print bステートメントが実行されると、a置き換えられたのではなく、インプレースで変更されたかどうかを確認できます。別の可能性はprint b is a、両方がまだ同じオブジェクトを参照しているかどうかを確認することでした。
以下のループはすでに見た要素を変更するだけなので、許容できると考えられます:
a = ['a',' b', 'c ', ' d ']
for i, s in enumerate(a):
a[i] = s.strip()
print(a) # -> ['a', 'b', 'c', 'd']
これは以下とは異なります:
a[:] = [s.strip() for s in a]
一時的なリストの作成や、元のリストを置き換えるための一時的なリストの割り当ては必要ありませんが、より多くのインデックス操作が必要です。
注意:この方法でエントリを変更できますが、list問題が発生する可能性を危険にさらさずにのアイテム数を変更することはできません。
これが私の意味の例です—エントリを削除すると、その時点からインデックスが混乱します。
b = ['a', ' b', 'c ', ' d ']
for i, s in enumerate(b):
if s.strip() != b[i]: # leading or trailing whitespace?
del b[i]
print(b) # -> ['a', 'c '] # WRONG!
(必要なアイテムがすべて削除されなかったため、結果は間違っています。)
更新
これはかなり人気のある回答なので、「インプレース」でエントリを効果的に削除する方法を次に示します(正確には問題ではありません)。
b = ['a',' b', 'c ', ' d ']
b[:] = [entry for entry in b if entry.strip() == entry]
print(b) # -> ['a'] # CORRECT
for i in aですか?これは非常に直感に反し、他の言語とは一見異なるように思われ、コードでエラーが発生し、長期間デバッグする必要がありました。Pythonチュートリアルはそれについてさえ言及していません。それには何らかの理由があるに違いありませんが?
a[i]とs)を使うのですか?むしろやりたいですa[i] = a[i].strip()。
a[i] = s.strip()インデックス作成操作は1つだけなので。
enumerate(b)はすべての反復でインデックス作成操作を実行し、別の操作をで実行していますa[i] =。私の知る限り、ループの反復ごとに1つのインデックス付け操作だけでPythonにこのループを実装することは不可能です:(
forループのバリアントがもう1つあり、enumerate()を使用するよりもきれいに見えます。
for idx in range(len(list)):
list[idx]=... # set a new value
# some other code which doesn't let you use a list comprehension
range(len(list))、Pythonのようなコードの匂いを使用することを検討しています。
enumerateはジェネレーターなので、list.ofタプルを作成するのではなく、リストを反復処理するときに一度に1つずつ作成します。どちらが遅いかを知る唯一の方法は、となるでしょうtimeit。
Jemshit IskenderovとIgnacio Vazquez-Abramsの答えは本当に良いです。この例でさらに説明できます。
a)2つのベクトルのリストが提供されます。
b)リストを走査して、配列のそれぞれの順序を逆にしたい
あなたが持っているとしましょう
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i = i[::-1] # this command does not reverse the string
print([v,b])
あなたが得るでしょう
[array([1, 2, 3, 4]), array([3, 4, 6])]
一方、もし
v = np.array([1, 2,3,4])
b = np.array([3,4,6])
for i in [v, b]:
i[:] = i[::-1] # this command reverses the string
print([v,b])
結果は
[array([4, 3, 2, 1]), array([6, 4, 3])]
削除する文字列を決定するための基準が何であるかは質問からは明らかではありませんが、削除する文字列のリストを持っている、または作成できる場合は、次のことを行うことができます。
my_strings = ['a','b','c','d','e']
undesirable_strings = ['b','d']
for undesirable_string in undesirable_strings:
for i in range(my_strings.count(undesirable_string)):
my_strings.remove(undesirable_string)
my_stringsを['a'、 'c'、 'e']に変更します