3

itertoolsライブラリは一般的に非常に役立つので、ライブラリに関する知識を深めようとしています。そのために、出くわしたインタビューパズルを解こうとしています。その大部分は、数値内でグループ化され、繰り返される数字の数を順番にカウントすることを含みます。たとえば、番号の場合:

1223444556

私が欲しい:

[(1,1),(2,2),(1,3),(3,4),(2,5),(1,6)]

つまり、左から右に、1 が 1、2 が 2、1 が 3 などです。

これが私の現在のコードです:

from itertools import groupby
groups_first = [int(''.join(v)[0]) for k,v in groupby(str(1223444556))]
counts = [len(''.join(v)) for k,v in groupby(str(1223444556))]
zip(counts,groups_first)

それは機能しますが、私が知りたいのは、2 つのリストを一緒に圧縮することを回避する、よりコンパクトな方法があるかどうかです。何かご意見は?これは、groupby() である種のラムダ関数を実行することになると思いますが、まだわかりません。

ありがとう!

4

3 に答える 3

2

私はおそらくただ書くだろう

>>> n = 1223444556
>>> [(len(list(g)), int(k)) for k,g in groupby(str(n))]
[(1, 1), (2, 2), (1, 3), (3, 4), (2, 5), (1, 6)]
于 2013-01-31T04:11:23.510 に答える
2

どうですか:

[(sum(1 for _ in v), int(k)) for k,v in groupby(str(1223444556))]
于 2013-01-31T04:11:25.297 に答える
1

代わりにコレクションを選ぶでしょう:

>>> from collections import Counter
>>> c = Counter('1223444556')
>>> c.items()
[('1', 1), ('3', 1), ('2', 2), ('5', 2), ('4', 3), ('6', 1)]

順序が重要な場合 (コメントで述べているように)、これはもはや最も効率的な方法ではない可能性があります。しかし、十分に検討するために、これを行うことができます:

>>> t = c.items()
>>> t = sorted(t)

y, x を x, y としてリストしたい場合は、次のようにします。

>>> t = [(y, x) for x, y in t]
>>> print t
[(1, '1'), (2, '2'), (1, '3'), (3, '4'), (2, '5'), (1, '6')]

このメソッドの 1 つの値は、繰り返される要素が文字列としてリストされることです。そのため、どの番号が元のリストに由来し、どの番号が頻度を示しているかについて混乱することはありません。

于 2013-01-31T04:13:29.603 に答える