[解決済み】リスト内の項目が存在する場合、それを削除する方法は?
質問
私は
new_tag
を持つフォームのテキストフィールドから
self.response.get("new_tag")
と
selected_tags
というチェックボックスフィールドから
self.response.get_all("selected_tags")
このように組み合わせています。
tag_string = new_tag
new_tag_list = f1.striplist(tag_string.split(",") + selected_tags)
(
f1.striplist
はリスト内の文字列の中の空白を取り除く関数です)。
しかし、その場合
tag_list
は空だが(新しいタグが入力されていない)、いくつかの
selected_tags
,
new_tag_list
は空の文字列を含んでいます
" "
.
例えば
logging.info
:
new_tag
selected_tags[u'Hello', u'Cool', u'Glam']
new_tag_list[u'', u'Hello', u'Cool', u'Glam']
空文字列を取り除くにはどうしたらいいですか?
リストの中に空の文字列がある場合。
>>> s = [u'', u'Hello', u'Cool', u'Glam']
>>> i = s.index("")
>>> del s[i]
>>> s
[u'Hello', u'Cool', u'Glam']
しかし、空文字列がない場合は
>>> s = [u'Hello', u'Cool', u'Glam']
>>> if s.index(""):
i = s.index("")
del s[i]
else:
print "new_tag_list has no empty string"
しかし、これは与える。
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
if new_tag_list.index(""):
ValueError: list.index(x): x not in list
なぜこのような現象が起こるのか、また、どのように回避すればよいのか。
解決方法は?
1)ほぼ英文スタイル。
を使用して存在感をテストします。
in
演算子を適用し、さらに
remove
メソッドを使用します。
if thing in some_list: some_list.remove(thing)
は
remove
メソッドは、最初に出現した
thing
すべての出現回数を削除するには
while
の代わりに
if
.
while thing in some_list: some_list.remove(thing)
- シンプルで、小さなリストには最適です。
2) ダックタイピング , EAFP のスタイルになります。
Pythonでは、このような「先手必勝」「後手必問」の姿勢が一般的です。オブジェクトが適切かどうかを事前にテストする代わりに、ただ操作を実行し、関連する例外をキャッチします。
try:
some_list.remove(thing)
except ValueError:
pass # or scream: thing not in some_list!
except AttributeError:
call_security("some_list not quacking like a list!")
もちろん、上の例の2番目のexcept節は、ユーモアに欠けるだけでなく、全く不要である(ポイントは、この概念をよく知らない人のためにダックタイピングを説明することであった)。
複数回のthingの出現が予想される場合。
while True:
try:
some_list.remove(thing)
except ValueError:
break
- この特定の使用例では少し冗長ですが、Pythonでは非常にイディオムです。
- これは#1よりも性能が良い
- PEP 463 は、ここで便利な try/except の単純な使用法のための短い構文を提案しましたが、承認されませんでした。
しかし contextlib の suppress() コンテキストマネージャである (python 3.4で導入)上記のコードは次のように簡略化できます。
with suppress(ValueError, AttributeError):
some_list.remove(thing)
繰り返しになりますが、thingの複数回出現が予想される場合。
with suppress(ValueError):
while True:
some_list.remove(thing)
3)機能的なスタイル
1993年頃、Pythonは
lambda
,
reduce()
,
filter()
と
map()
を提供します。
Lisp
ハッカーがそれを見逃して、動作するパッチを提出しました*。また
filter
を使えば、リストから要素を削除することができます。
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
あなたのケースに役立つショートカットがあります:空のアイテム(実際には
bool(item) == False
のように
None
ゼロ、空文字列、その他の空のコレクション)、最初の引数としてNoneを渡すことができます。
cleaned_list = filter(None, some_list)
-
[更新]をクリックします。
: Python 2.x では。
filter(function, iterable)
と等価であった。[item for item in iterable if function(item)]
(または[item for item in iterable if item]
は、最初の引数がNone
); Python 3.xでは、これと同等になりました。(item for item in iterable if function(item))
. 微妙な違いは、以前は filter がリストを返していましたが、現在はジェネレータ式のように動作することです - クリーンアップされたリストを繰り返し処理し、それを破棄するだけなら問題ありませんが、本当にリストが必要な場合はfilter()
の呼び出しはlist()
コンストラクタを使用します。 -
*これらのLispy風味のコンストラクトは、Pythonでは少し異質とされています。2005年頃
グイドは
filter
- コンパニオンと一緒にmap
とreduce
(まだ消えてはいませんがreduce
に移動されました。 ファンクツール が好きな人は一見の価値ありです。 高次関数 ).
4)数学的スタイル
リスト内包
がバージョン 2.0 で導入されて以来、Python のリスト操作の好ましいスタイルとなりました。
PEP 202
. その根拠は、リスト内包は、以下のような状況でリストを作成するための、より簡潔な方法を提供することです。
map()
と
filter()
とかネストされたループが現在使われているはずです。
cleaned_list = [ x for x in some_list if x is not thing ]
ジェネレータ式は、バージョン2.4で導入された PEP 289 . ジェネレータ式は、メモリ上に完全なリストを作成する必要がない(または、作成したくない)場合、例えば、要素を一度に一つずつ繰り返し処理したい場合に適しています。リストに対して反復処理を行うだけであれば、ジェネレータ式は次のように考えることができます。 遅延評価 リスト内包
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
- 参照 このPythonの歴史ブログ 投稿者 GvR .
- この構文は セットビルダー記法 を数学で表現しています。
- Python 3 はまた セット と ディクショナリ .
注意事項
-
という不等号演算子を使いたい場合があります。
!=
の代わりにis not
( この違いが重要です ) - リストのコピーを意味するメソッドを批判する人へ:一般に信じられていることとは逆に、ジェネレータ式はリスト内包よりも常に効率的とは限りません。
関連
-
[解決済み】Python regex AttributeError: 'NoneType' オブジェクトに 'group' 属性がない。
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] リスト内のアイテムのインデックスを検索する
-
[解決済み] リストが空かどうかを確認するにはどうすればよいですか?
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] リストを均等な大きさの塊に分割するには?
-
[解決済み] リストの最後の要素を取得する方法
-
[解決済み] リストからランダムに項目を選択するにはどうすればよいですか?
-
[解決済み] リスト項目の出現回数を数えるにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】RuntimeWarning: invalid value encountered in double_scalars で numpy の除算ができない。
-
[解決済み】ImportError: sklearn.cross_validation という名前のモジュールがない。
-
[解決済み】numpy: true_divide で無効な値に遭遇
-
[解決済み】ImportError: PILという名前のモジュールがない
-
[解決済み】"No JSON object could be decoded "よりも良いエラーメッセージを表示する。
-
[解決済み】インポートエラー。モジュール名 urllib2 がない
-
[解決済み】IndexError: invalid index to scalar variableを修正する方法
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】Python: SyntaxError: キーワードは式になり得ない
-
[解決済み】Python !=操作 vs "is not "操作