1

入力

a = [
        [1, 'abc', '123'],
        [1, 'def', '456'],
        [2, 'ghi', '789'],
        [2, 'jkl', '012'],
        [2, 'mno', '345'],
        [3, 'pqr', '678']
    ]

以下の目的の出力を達成するための最良の方法は何ですか? 入力リストaが巨大になることに注意してください (~100K)。

出力

a = [
        [1, 'abc;def', '123;456'],
        [2, 'ghi;jkl;mno', '789;012;345'],
        [3, 'pqr', '678']
    ]

ノート:

  • 要素は、Column1 に基づいてグループ化されます。
  • 要素の順序は重要ではありません (任意の順序にすることができます)。
  • 後続の列は、区切り記号によって連結されます;
  • 最初の列を除いて、他のすべての列は文字列フィールドです。
4

3 に答える 3

1

パフォーマンスについてはわかりませんが、itertools.groupbyを使用して [各サブリストを 1 つのフラット リストにするように編集] のようにするかもしれません。

>>> from itertools import groupby
>>> from operator import itemgetter
>>> [[k] + [';'.join(v) for v in zip(*g)[1:]] for k,g in groupby(a, itemgetter(0))]
[[1, 'abc;def', '123;456'], [2, 'ghi;jkl;mno', '789;012;345'], [3, 'pqr', '678']]

これは、リストがサブリストの最初の要素で連続していることを前提としています。そうでない場合は、を置き換える必要がありgroupbyます

groupby(sorted(a, key=itemgetter(0)), itemgetter(0))

代わりは。

上記はいくつかのトリックを使用しています。

  1. groupby、キー関数の値によって iterable 内の連続する要素をグループ化します
  2. itemgetter、基本的に要素をすばやく取得します。itemgetter(0)基本的には高速ですlambda x: x[0]
  3. zip(*g)zip、これは、組み合わせと*タプルのアンパックによって物事を転置するための一般的なイディオムですzip(*([1,2],[3,4])) == [(1, 3), (2, 4)]。(とにかく、Python 2 では、3 ではそれを作成する必要がありますlist(zip(..))。)
于 2013-10-17T14:57:17.530 に答える
0

これは私がこれまでに得たものです。誰かがこのコードにいくつかのコードを投げることができれば、それは素晴らしいことです:

a = [
        [1, 'abc', '123'],
        [1, 'def', '456'],
        [2, 'ghi', '789'],
        [2, 'jkl', '012'],
        [2, 'mno', '345'],
        [3, 'pqr', '678']
    ]
    count = 2
    index = 1
    prev_val = a[index][0]
    output = []
    first_ele = a[0]

while index < len(a)+1:
    if prev_val == count:
        output[first_ele][1] += ';' + a[index][1] + str(a[index][2])
    else:
        count += 1
        index += 1`
于 2013-10-17T16:13:39.233 に答える