Traceback (most recent call last):
File "D:\projects\exercise_openpyxl\exe40_slimmed\exe43_slimmed_dict\slimmed_dict_.py", line 22, in <module>
company_list =[ row[0].value for row in ws["B2:B" + str(ws.max_row)] if row[0].value not in company_list]
File "D:\projects\exercise_openpyxl\exe40_slimmed\exe43_slimmed_dict\slimmed_dict_.py", line 22, in <listcomp>
company_list =[ row[0].value for row in ws["B2:B" + str(ws.max_row)] if row[0].value not in company_list]
NameError: name 'company_list' is not defined
最終行を読むと、「company_list という名前が(文脈的には、「変数が」)宣言されていません」と書かれていますね。 内包表記内で if .. not in company_list というのがありますが、この行の手前までで company_list というものはありません。 イコール「 = 」の右辺側の演算を終えたあとの戻り値の受け取りように左辺にありますが、右辺の計算時にはまだないものなのでエラーになります。
ここが分かれば以下についても解決します。
> 内包表記の上にcompany_list =[]と宣言を付けてみるとエラーはおきなかったですが
company_list =[] ということですでに登場していれば上で紹介したエラーはでません。 ですが、内包表記後半の if row[0].value not in company_list で言う company_list は常に [] ですね。 すると、「その状態で演算した結果で、改めて左辺に置いた company_list を上書きする」という意味になります。
「重複しないリストを作る」という趣旨はこれでは達成できないです。
で、「内包表記できるか」という当初の問いについて回答すると、「戻り値をリストとするならば無理」と思います。 集合内包表記であれば可能かと。 集合にしてしまうと要素の順序が破壊されてしまいますが、「どこかに出力するときには、それでも順序を復元してからにしたい」ということであれば、集合内包表記で作った集合を list 関数でリストにして、それに対して sort または sorted で処理をすることになるかと思います。
大本さんの投稿
(投稿ID: 5396)
色々と試してみたのですが、エラーがおきてできませんでした。
①原文
②試してみた事
再帰的に下記でいけるかと思いましたがエラーでした。
また内包表記の上にcompany_list =[]と宣言を付けてみるとエラーはおきなかったですが、list、dict共に想定したデータが取れませんでした。
内包表記が出来るなら、どう書けば良いか教えて下さい。
小川 慶一さんのコメント
(コメントID: 7884)
今後、エラーが出る場合は、エラーのスタックトレースを貼ってください。
そして、できれば、投稿前に、そのスタックトレースを自分なりに読んで、エラーの理由の見当をつけてみてください。
あと、エラーを再現可能なコードを載せていただければと思います。
なお、「たぶんこんなところかな」ということであたりをつけて僕が書いたコードで出たエラースタックトレースは以下のとおりです。
最終行を読むと、「company_list という名前が(文脈的には、「変数が」)宣言されていません」と書かれていますね。
内包表記内で if .. not in company_list というのがありますが、この行の手前までで company_list というものはありません。
イコール「 = 」の右辺側の演算を終えたあとの戻り値の受け取りように左辺にありますが、右辺の計算時にはまだないものなのでエラーになります。
ここが分かれば以下についても解決します。
> 内包表記の上にcompany_list =[]と宣言を付けてみるとエラーはおきなかったですが
company_list =[] ということですでに登場していれば上で紹介したエラーはでません。
ですが、内包表記後半の if row[0].value not in company_list で言う company_list は常に [] ですね。
すると、「その状態で演算した結果で、改めて左辺に置いた company_list を上書きする」という意味になります。
「重複しないリストを作る」という趣旨はこれでは達成できないです。
で、「内包表記できるか」という当初の問いについて回答すると、「戻り値をリストとするならば無理」と思います。
集合内包表記であれば可能かと。
集合にしてしまうと要素の順序が破壊されてしまいますが、「どこかに出力するときには、それでも順序を復元してからにしたい」ということであれば、集合内包表記で作った集合を list 関数でリストにして、それに対して sort または sorted で処理をすることになるかと思います。
大本さんのコメント
(コメントID: 7885)
>今後、エラーが出る場合は、エラーのスタックトレースを貼ってください。
>そして、できれば、投稿前に、そのスタックトレースを自分なりに読んで、エラーの理由の見当をつけてみてください。
>あと、エラーを再現可能なコードを載せていただければと思います。
分かりました!お手数をおかけしました。
小川先生の考えられた通りのメカニズムでした。
①内包表記を試してみたら下記エラーが出ました
>NameError: name 'company_list' is not defined
②内包表記の上にcompany_list =[]を付けたら、「その状態で演算した結果で、改めて左辺に置いた company_list を上書きする」が
おこり、先に登場したデータが後から登場したデータに上書きされてしまっていました。
>「内包表記できるか」という当初の問いについて回答すると、「戻り値をリストとするならば無理」と思います。
>集合内包表記であれば可能かと。
集合内包表記にすると順番は破壊されるものの、会社名の取得は出来ました。
順番の復元についてlistやdictを使って色々トライしてみましたが現時点では上手くいかなかったので、今回はここまでにして先に進めようと思います。
有難うございました。
小川 慶一さんのコメント
(コメントID: 7886)
list の sort については、noteでの以下の投稿が参考になるかと思います。
https://forum.pc5bai.com/note/entry/6adff5eb-040d-4af2-8682-0371b6a1c9bb/
以下の箇所ですね。
この投稿だけ読んでも lambda 関数のところが理解できないかもしれませんが、以降のコメントをまずは読みすすめてみてください。(lambda に関するところの拾い読みからでも)
さらに端折るならば、以下での僕のコメントを。
https://forum.pc5bai.com/note/entry/6adff5eb-040d-4af2-8682-0371b6a1c9bb/#cid-cb95da6f-6218-49c9-aeba-8e99987c2da5
藤本 博子さんのコメント
(コメントID: 7887)
はじめまして。藤本と申します。
「重複しないリストを作る」リスト内包表記のご質問の投稿、大変参考になりました。
確かに集合内包表記だと可能ですね。
ただし、漢字はUnicodeコードポイント(文字コード)の順にソートされ、漢字のふりがな昇順の並び替えはできないようですね。
https://note.nkmk.me/python-pandas-sort-in-any-order/
Unicodeと漢字の説明のリンクをみつけましたが、自分が飽和状態になりました。
https://www.kanzaki.com/docs/jcode.html#unicode
exe42のslimmed_listだったら、E列_英数字組合せの文字列"信憑番号"は、
sorted関数+集合内包表記の書き方ができるのですね。
大木さんが質問くださったので、自分もコードを書いて確認するきっかけをいただけました。
ありがとうございます!
藤本 博子さんのコメント
(コメントID: 7888)
大本さんのお名前を、大木さんと読み間違えてました。
大変失礼いたしました
申し訳ございません。<(_ _)>
大本さんのコメント
(コメントID: 7889)
listのsortについての使い方の例を有難うございます。
【lambda は無名関数によく使われるラベリング】なのですね。
自分でも調べてトライしてみます。
藤本さん
初めまして。
いつも面白いコードを共有して下さり有難うございます。
今回もsort関数やlamdaの使い方のサンプルや有効な情報を有難うございます。
参考にして自分でもトライしてみます!
名前も気にしないでください!
関東では【大木】さんが多いらしく、よく間違えられます。
西日本では【大元】さんが多いらしく、たまに間違えられます。
似たような字が並ぶ名前なので【木本】さんと間違えらる事もあり面白いですよ。