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

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

ただいまの
回答率

89.63%

文字列を比較して配列に格納できない

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 1,866
退会済みユーザー

退会済みユーザー

ans配列の要素の文字列の最初の文字がlinesの要素の最初の文字と一致するならlinesの2番目の要素('A'/'B'/'C'/'D')をline_alpha配列に格納する、というシステムを作りたいです。

lines = [['cat', 'A'], ['dog', 'B'], ['rabbit', 'C'], ['daisy', 'D']]

ans = [['c'], ['d']]

for i in range(4):
    line_alpha =[]
    for j in range(5):
        eqe_ans = str(ans[j])
        if lines[j][0].startswith(eqe_ans) == True:
          line_alpha.append(lines[j][1])
print(line_alpha)


とコードを書いて実行すると[]がprintで出力されました。
デバックしてみると

if lines[j][0].startswith(eqe_ans) == True:


がTrueになる条件がこのコードではないようで。
本来なら、

[['A'],['B','D']]


と出力させたいです。('dog'・'daisy'のように先頭の文字が同じもののlinesの1番目の要素は二次元配列の要素としてひとまとめにしたい)
デバック時に

line_alpha = '[\\'d'\\']'


が取れているようで'[\\'と余計なものが入っていて条件式が満たされないのかと思うのですが解決策がわからず...。どう直せばよいでしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

0

とりあえず、質問の

'[\\'と余計なものが入っていて

の部分から。

これは、今回のコードにおいて、ans[0]には ['c'] とリストの中に文字列型の'c'が格納されているのですが、eqe_ans = str(ans[j])としていきなり全体を文字列に変えていることに起因しております。

本来ここで必用なことは、ans[0]の内部にある文字列を取り出してstartswith() の引数に渡す

    eqe_ans = ans[j][0]
    if lines[j][0].startswith(eqe_ans) == True:


または、リストをタプル型に変更してstartswith()に渡す

    eqe_ans = tuple(ans[j])
    if lines[j][0].startswith(eqe_ans) == True:


なのではないでしょうか。


次に、for文での index絡みの問題点が何箇所かあります。

for i in range(4):
    line_alpha =[]
    for j in range(5): #ans の範囲は(0~1)なのでは?
        eqe_ans = str(ans[j])
        #↓ linesのインデックスは jではなくてiなのでは?
        if lines[j][0].startswith(eqe_ans) == True:
            #↓ linesのインデックスは jではなくてiなのでは?
            line_alpha.append(lines[j][1])

基本的にfor文は(indexを使う必要性が無い場合)リストの要素でループを回すようにしてください。
このようすることで、 indexの取り違いや範囲の間違いは少なくなります。

for word, symbol in lines:
    for prefix in ans:
        …

で、更に

  • 内側のループと外側のループを入れ替える
  • 全体の結果を格納するためのリスト(res)と各ワード毎の結果を格納するためのリスト(line_alpha)を分け、ループ毎に line_alpharesappend()するようにする

の部分で大きく構成を変えて・・
たぶんやりたい事はこんな感じになるのではないでしょうか。

lines = [['cat', 'A'], ['dog', 'B'], ['rabbit', 'C'], ['daisy', 'D']]
ans = [['c'], ['d']]

res = []
for prefix, in ans:
    line_alpha =[]
    for word,symbol in lines:
        if word.startswith(prefix):
            line_alpha.append(symbol)
    res.append(line_alpha)
print(res)
# => [['A'],['B','D]]

更に内側のループを内包表記にするとこんな感じです。

lines = [['cat', 'A'], ['dog', 'B'], ['rabbit', 'C'], ['daisy', 'D']]
ans = [['c'], ['d']]

res = []
for prefix, in ans:
    line_alpha =[symbol for word,symbol in lines if word.startswith(prefix)]
    res.append(line_alpha)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

問題点が2つあります。

1)

for i in range(4):
    line_alpha =[]


i(linesで調べる要素のインデックス)が変わるたびに、結果を入れる配列 line_alpha を空にしているので、それ以前に見つけた「一致する要素」が消えてしまっています。

2)

    for j in range(5):
        eqe_ans = str(ans[j])


質問のコードで、ansは要素数2のリストですが、ansのインデックスが range(5) になっています。
リストの要素を全部調べる際には、直接数値を書くのではなく、len関数で要素数を調べるべきです。

これらを反映した以下のコードを試してみてください。

lines = [['cat', 'A'], ['dog', 'B'], ['rabbit', 'C'], ['daisy', 'D']]

ans = [['c'], ['d']]

line_alpha =[]

for i in range(len(lines)):
    for j in range(len(ans)):
        eqe_ans = str(ans[j])
        if lines[j][0].startswith(eqe_ans) == True:
          line_alpha.append(lines[j][1])
print(line_alpha)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

startswithを使ってうまくいけるかなぁと思って、少し長くなりますが、違う方法で次のようにやってみました
よろしかったら参考願います

lines = [['cat', 'A'], ['dog', 'B'], ['rabbit', 'C'], ['daisy', 'D']]
ans = [['c'], ['d']]
line_alpha =[]

ans_f = [ans[i][0] for i in range(len(ans))]
lines_f = [lines[i][0][0] for i in range(len(lines))]
for i in ans_f:
    arr = [lines[index][1] for index, item in enumerate(lines_f) if i == item]
    if arr != []:
        line_alpha.append(arr)

print(line_alpha)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

もう解決済みですが

lines = [['cat', 'A'], ['dog', 'B'], ['rabbit', 'C'], ['daisy', 'D']]
ans = [['c'], ['d']]
line_alpha = [[line[1] for line in lines if a[0]==line[0][0]] for a in ans]
print(line_alpha )


pythonのfor文は他の言語でのforeachに相当するので、わざわざfor i in range(len(list))みたいな書き方をする必要はないです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる