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

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

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

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

Q&A

解決済

5回答

588閲覧

同じ文字列をカウントして出力する

ryo_py

総合スコア25

Python

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

0グッド

0クリップ

投稿2020/01/18 09:27

下のリストの'a'を数えて[2, 1, 3]と出力したいのですがいい方法が思いつきません。

python

1st = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] 2 3count = 0 4lis = []__イタリックテキスト__ 5for s in st: 6 if s == 'a': 7 count += 1 8 else: 9 if count > 0: 10 lis.append(count) 11 count = 0 12

上の方法だと、最後の'a'を見た後lisに3が追加されません。
解決策として文字列の最後に'.'を加える方法を考えましたが、あまり良くない手だと思うので、他に良い方法があれば教えて下さい。

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

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

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

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

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

guest

回答5

0

ベストアンサー

forループが終わったあとに

python

1if count > 0: 2 lis.append(count)

を付け加えるのはいかがでしょう?

ちなみに、こんな書き方もできます。

python

1st = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] 2lis = [*map(len, ''.join(' a'[s == 'a'] for s in st).split())] 3print(lis)

投稿2020/01/18 09:33

編集2020/01/18 10:10
shiracamus

総合スコア5406

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

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

ryo_py

2020/01/18 10:10

ありがとうございました。 内包表現が苦手なのですが、連続したaだけでくっつけてそれを数えているという様な処理ですかね?(汗 1つ分からないのですが、どうしてmapの前に*がついているのでしょうか?
shiracamus

2020/01/18 10:26 編集

* は要素展開です。 list(map(...)) と書く代わりに、 [*map(...)] と書いて、リストリテラルの中に mapで生成された要素を展開することができます。
shiracamus

2020/01/18 10:27 編集

>>> st = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] >>> ' a'[False] ' ' >>> ' a'[True] 'a' >>> [' a'[s == 'a'] for s in st] ['a', 'a', ' ', ' ', 'a', ' ', 'a', 'a', 'a'] >>> ''.join(' a'[s == 'a'] for s in st) 'aa a aaa' >>> 'aa a aaa'.split() ['aa', 'a', 'aaa'] >>> list(map(len, ['aa', 'a', 'aaa'])) [2, 1, 3] >>> [*map(len, ['aa', 'a', 'aaa'])] [2, 1, 3]
shiracamus

2020/01/18 10:44 編集

もし、stの要素が'a' か '_' のどちらかしかないという条件があれば、 lis = [*map(len, ''.join(st).replace('_', ' ').split())] でいけます。
ryo_py

2020/01/18 10:38

細かく解説してくださり、ありがとうございます。 この考え方は思いつかなかったので勉強になりました。
guest

0

2つの方法を書いてみました。

python3

1[len(x) for x in re.split('[^a]+', "".join(st))] 2 3list(map(lambda x: len(x), re.split('[^a]+', "".join(st))))

実行例:
イメージ説明

追記:
コメントで指摘があった
"aaa" のようなデータがあった場合
にも動作するように修正しました。

python

1st2 = ['a' if s == 'a' else '_' for s in st] 2[len(x) for x in re.split('[^a]+', "".join(st2))]

実行例
イメージ説明

投稿2020/01/19 07:56

編集2020/01/19 08:51
katoy

総合スコア22324

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

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

shiracamus

2020/01/19 08:01

import re が必要ですね。 src = ['aaaaaa', '_', '_', 'a', '_', 'a', 'a', 'a'] みたいなデータがあったときの結果をどうしたらいいのかわからないので、もしかすると要素が 'a' か確認する必要があるかもしれません。
katoy

2020/01/19 08:52

修正案を回答mに追記しました。
guest

0

既に解決済みですが、参考までに。
このような処理ではitertools.groupbyが便利です。

Python

1import itertools 2 3 4src = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] 5dst = [] 6 7for s, it in itertools.groupby(src, lambda s: s == 'a'): 8 if not s: 9 continue 10 11 l = sum(1 for _ in it) 12 dst.append(l) 13 14print(dst)

実行結果 Wandbox

[2, 1, 3]

内包表記を使うと更に簡潔です。慣れるまでは少し読みづらいですが。

Python

1import itertools 2 3 4src = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] 5dst = [ 6 sum(1 for _ in it) 7 for s, it in itertools.groupby(src, lambda s: s == 'a') 8 if s 9] 10 11print(dst)

解決策として文字列の最後に'.'を加える方法を考えましたが、あまり良くない手だと思う

番兵法ですね。簡単に解決できる良い方法だと思います。
ただ番兵として使うのであればNULL文字など通常使わない文字を用いた方が良いかと。

投稿2020/01/18 12:09

LouiS0616

総合スコア35660

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

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

ryo_py

2020/01/18 16:58

ありがとうございます。 自分も調べているうちにitertools.groupbyを見つけたのですが、setを使っていて、頭が?となり、読み飛ばしてしまいました笑。 番兵法。知らなかったので調べてみましたが、こんな面白い考え方があるんですね。自分の解決策は確かにこの番兵法にちょっとだけ似てますね笑。勉強になります。
guest

0

これでどうでしょうか。

python

1 2st = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] 3 4count = 0 5lis = [] 6for s in st: 7 if s == 'a': 8 count += 1 9 else: 10 if count > 0: 11 lis.append(count) 12 count = 0 # インデント追加 13if count > 0: # 追加 14 lis.append(count) # 追加 15print(lis)

結果

[2, 1, 3]

投稿2020/01/18 09:43

ikapy

総合スコア1167

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

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

ryo_py

2020/01/18 10:05

ありがとうございます。 今回は先に同じ様な回答をくださった方をベストアンサーにさせていただきます。
guest

0

元のソースコードだと、配列の最後が 'a' だったときに lis に count を追加できませんでした。
そこで、s == 'a' のときであっても、もしそれが配列の最後であれば lis に count を追加するようにしました。

python

1st = ['a', 'a', '_', '_', 'a', '_', 'a', 'a', 'a'] 2st_length = len(st) 3 4count = 0 5lis = [] #__イタリックテキスト__ 6for i, s in enumerate(st): 7 if s == 'a': 8 count += 1 9 if i == st_length -1: 10 lis.append(count) 11 else: 12 if count > 0: 13 lis.append(count) 14 count = 0

補足

文字列の最後に'.'を加える方法

これは確かに良くない方法だと思います。避けるのが賢明だと感じました。

投稿2020/01/18 09:37

siruku6

総合スコア1382

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

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

siruku6

2020/01/18 09:39

shiracamusさんのおっしゃるように、最後に2行追加するだけの方が無駄がなくきれいだと思いました....orz
ryo_py

2020/01/18 10:06

ありがとうございます。 そうですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問