42347


様々なstr要素が含まれるリストから、日本語（ひらがな、カタカナ、漢字）以外の物を削除するコードを書いたのですが、何度も実行しないと全て消えてくれません。どうやら数字、アルファベットは一括で消すことが出来ても、記号を一つ消すたびにbreak(?)してしまうように見えるのですが・・・どうしたらいいのでしょうか。

[code]

    import re
    bag_of_things = ["あいうえお", "546", "たぬき", "饅頭", "abdf", "#%&", "aodih", "    ", "hello", "こんにちは"]
    nihongo = re.compile('[ぁ-んァ-ン一-龥]+')
    
    
    def clean(list):
        for item in list:
            if not nihongo.findall(item):
                print(item, "is not japanese")
                list.remove(item)
    
[/code]

[![結果\[1\]](https://i.stack.imgur.com/bMocf.png)

[![関数](https://i.stack.imgur.com/y8UhK.png)](https://i.stack.imgur.com/y8UhK.png)


CC BY-SA 3.0
2018-03-12T08:09:12.147
42344
2018-03-14T00:53:47.097
27710
question
python 正規表現
リストから日本語以外の要素を削除したい


申し訳ないです、自己解決しました。。。  
日本語の要素だけを含む新しいリストを作りました。。。

[code]

    nihongo = re.compile('[ぁ-んァ-ン一-龥]+')  # used in def clean(list):
    
    
    def clean(list):
        new_list = []
        for item in list:
            if nihongo.findall(item):
                new_list.append(item)
        return new_list
    
    list = clean(list)  # 日本語ワードだけを含むリストを作成。
    
[/code]


CC BY-SA 3.0
2018-03-12T08:43:44.917
42346
2018-03-12T08:43:44.917
27710
42344
answer


for文の途中で、forで回しているlistの要素を削除しているため、対象オブジェクトがずれてしまっているのが原因です。

[code]

    >>> L = list(range(10))
    >>> L
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> for l in L:
    ...     print(l)
    ...     L.remove(l)
    ... 
    0
    2
    4
    6
    8
    >>> L
    [1, 3, 5, 7, 9]
    
[/code]

対処方法はいくつかあります。  
1\. すでに自己解決されているように、対象リストから`remove`するのではなく対象を抽出して別のリストにいれるか。  
2\. ループは対象リストのコピーに対して行うか。

[code]

    >>> L = list(range(10))
    >>> for l in L[:]:
    ...     print(l)
    ...     L.remove(l)
    ... 
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> L
    []
    
[/code]


CC BY-SA 3.0
2018-03-12T08:51:10.757
42347
2018-03-12T08:51:10.757
806
42344
answer


既に解決済みとの事ですが、 reversed() 使っても良いのでは?

[code]

    def clean(list):
      for item in reversed(list):
            if not nihongo.findall(item):
                  print(item, "is not japanese")
                  list.remove(item)
    
[/code]

単に逆順からの検索を行うだけです。

* * *

追記

もっと簡単な方法がある筈と思ったら、

> **filter** (lambda item: nihongo.findall(item), list)

で良いみたいですね。


CC BY-SA 3.0
2018-03-12T12:48:28.907
42355
2018-03-12T14:19:45.967
2018-03-12T14:19:45.967
42344
answer


try this:

[code]

    def clean(list):
      return [e for e in list if nihongo.findall(e)]
    
    bag_of_things = clean(bag_of_things)
    
[/code]


CC BY-SA 3.0
2018-03-14T00:53:47.097
42377
2018-03-14T00:53:47.097
27732
42344
answer