質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

836閲覧

The kernel appears to have died. It will restart automatically.と吐いて計算をやめてしまう対処法について。

yu__

総合スコア108

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/02/20 06:07

編集2019/02/20 06:33

The kernel appears to have died. It will restart automatically.と吐いて計算をやめてしまう対処法について。

以下リスト内のリストをすべて外す関数を用いて。

python

1def flatten(data): 2 for item in data: 3 if hasattr(item, '__iter__'): 4 for element in flatten(item): 5 yield element 6 else: 7 yield item 8rensyu = [1,[1,2],3,[1,[1,2]]] 9print(list(flatten(rensyu)))

上記のコードを実行すると以下のような結果が返ってくる。

[1, 1, 2, 3, 1, 1, 2]

このようになる理由は分かっているつもりだったのですが、

python

1def flatten(data): 2 for item in data: 3 if hasattr(item, '__iter__'): 4 for element in flatten(item): 5 yield element 6 else: 7 yield item 8rensyu = [1,[1,2],3,[1,[1,2]],'Hello'] 9print(list(flatten(rensyu)))

rensyuというリストに'Hello'なる文字列を追加したとき
実行結果が以下のように帰ってきてしまいます。

RecursionError: maximum recursion depth exceeded

そこで以下のようなコードを追加することにより解決するというサイトを発見したので、
https://qiita.com/narupo/items/e25ac05a9065c0bd9c03

python

1import sys 2sys.setrecursionlimit(10000)

上記のコードを含め、再び以下のコードを実行したところ

python

1def flatten(data): 2 for item in data: 3 if hasattr(item, '__iter__'): 4 for element in flatten(item): 5 yield element 6 else: 7 yield item 8rensyu = [1,[1,2],3,[1,[1,2]],'Hello'] 9print(list(flatten(rensyu)))

以下の結果が返って来てしまいました。

The kernel appears to have died. It will restart automatically.

私としては、以下のような結果が得られればうれしいです。

[1, 1, 2, 3, 1, 1, 2,'Hello']

なぜエラーが発生してしまうか、
また、得られたらうれしい結果はどのようにすれば出すことができるか
教えて頂けると恐縮です。

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

文字列が要素に含まれた場合、文字列の要素も文字列なのでつねにhasattr(item, '__iter__')Trueになり無限に再帰関数が呼ばれます。
その結果RecursionError: maximum recursion depth exceededが発生します。
無限に再帰してしまうのでsys.setrecursionlimit(10000)にて再帰回数を制御しても効果はありません。

元のコードを生かしたまま修正するなら
if (not isinstance(item,str)) and hasattr(item, '__iter__'):
if isinstance(item,list): # リストのみの入れ子の場合
とすれば意図した動作になります。

投稿2019/02/20 06:56

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu__

2019/02/20 07:02

非常に簡潔に説明していただきありがとうございました。 理解できました!
guest

0

ベストアンサー

pythonでは文字列はイテレータにもなります。
なので、文字列'Hello'が'H', 'e', 'l', 'l', 'o'に分解されて、先頭の'H'がさらに分解されて'H'になって、その先頭の'H'が'H'に分解されて、その先頭の'H'が… と永久に続いていくため再帰呼び出しの段数超過でエラーになっているのだと思います。

期待する結果を出すだけであれば以下のようにif文に条件を追加して「イテレータでも文字列は分解しない」ようにすれば良いと思います。

python

1def flatten(data): 2 for item in data: 3 if hasattr(item, '__iter__') and not isinstance(item, str): 4 for element in flatten(item): 5 yield element 6 else: 7 yield item

投稿2019/02/20 06:52

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu__

2019/02/20 07:00

先頭の'H'がさらに分解されて'H'になって、その先頭の'H'が'H'に分解されて、その先頭の'H'が… と永久に続いていくため再帰呼び出しの段数超過でエラーになっているのだと思います。 上記の説明が非常に分かりやすく簡単に理解できました! 数値はイテラブルではないが文字列はイテラブルということですね。 非常に分かりやすく説明していただいたので、ベストアンサーにさせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問