私がリストを持っていると仮定します。
temp = ['A', 'B', 'A', 'B', 'A', 'B']
内部の文字列のカウントを結合する方法を探しています。
意図した出力:
['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
リスト内包表記を使用して解決できましたが、リストを指定する必要がない方法を探しています[1, 1, 2, 2, 3, 3]
。出来ますか?
[j + "_" + str(i) for i, j in Zip([1, 1, 2, 2, 3, 3], temp)]
collections.defaultdict
for
ループあり:
from collections import defaultdict
L = ['A', 'B', 'A', 'B', 'A', 'B']
dd = defaultdict(int)
res = []
for item in L:
dd[item] += 1
res.append(f'{item}_{dd[item]}')
print(res)
['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
Counter
またはdefaultdict(int)
を使用して、キャラクターに遭遇したときにキャラクターが何回見られたかを追跡できます。
_>>> from collections import Counter
>>>
>>> temp = ['A', 'B', 'A', 'B', 'A', 'B']
>>> seen = Counter()
>>>
>>> result = []
>>> for c in temp:
...: seen.update(c)
...: result.append('{}_{}'.format(c, seen[c]))
...:
>>> result
>>> ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
_
temp
に複数の文字を含む文字列が予想される場合、seen.update(c)
は予期しない結果をもたらす可能性があることに注意してください。デモ:
_>>> seen = Counter()
>>> seen.update('ABC')
>>> seen
>>> Counter({'A': 1, 'B': 1, 'C': 1})
_
カウント方法と期待するデータの種類によっては、この行を使用することをお勧めします
_seen[c] += 1
_
の代わりに
_seen.update(c)
_
または、インポートなしで:
_>>> seen = {}
>>> result = []
>>>
>>> for c in temp:
...: seen[c] = seen.get(c, 0) + 1
...: result.append('{}_{}'.format(c, seen[c]))
...:
>>> result
>>> ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
_
辞書を使用できます(または、さらに良いことに、 collections.defaultdict
)各アイテムのカウントを維持するには:
from collections import defaultdict
lst = ['A', 'B', 'A', 'B', 'A', 'B']
lst2 = []
d = defaultdict(int)
for item in lst:
d[item] += 1
lst2.append('{}_{}'.format(item, d[item]))
print(lst2) # ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
ここでリスト内包表記を使用するには、元のリストを反復するときに各アイテムの状態(つまり、カウンター)を更新する方法が必要になります。そのためには、デフォルトの引数を持つ関数を使用できます。例:
def get_count(item, d=defaultdict(int)):
d[item] += 1
return '{}_{}'.format(item, d[item])
lst2 = [get_count(item) for item in lst]
print(lst2) # ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
実際、(OPがいくつかのコメントで求めているように)これをリスト内包表記だけで、あまり多くの望ましくない副作用なしに行うことは可能です。ただし、これが必ずしも良いアイデアであるかどうかはわかりません。理解しやすいコードではない場合もあります。
from collections import defaultdict
import itertools
temp = ['A', 'B', 'A', 'B', 'A', 'B']
result = [j + "_" + str(next(c[j]))
for c in [defaultdict(itertools.count)]
for j in temp]