0

ASCIIファイルからデータを読み取っているときに、次のようなことをしていることに気付きます。

(a, b, c1, c2, c3, d, e, f1, f2) = (float(x) for x in line.strip().split())
c = (c1, c2, c3)
f = (f1, f2)

1行あたりの要素数が決まっている場合(これは私が行います)¹、解凍する複数要素のエントリが1つしかない場合は、 `(a、b、* c、d、e)= ...'(拡張された反復可能な解凍)。

そうしない場合でも、もちろん、上記の例の2つの複数要素エントリの1つ(a, b, *c, d, e, f1, f2) = ...をスター付きコンポーネントに置き換えることができます。

私の知る限り、itertoolsここではすぐには使用できません。

私がおそらく気付いていない理由で「よりPythonic」と見なされる可能性のある上記の3行のコードに代わるものはありますか?

¹それは決定的ですが、それでも行ごとに異なります。パターンは、numpys関数loadtxtまたは。に対して複雑すぎgenfromtxtます。

4

2 に答える 2

1

このようなステートメントを頻繁に使用し、そのようなパターンを頻繁に記述するのではなく、コードの柔軟性と再利用性を最大限に高めたい場合は、そのための小さな関数を作成することをお勧めします。モジュールに入れてインポ​​ートするだけです(作成したスクリプトをインポートすることもできます)。

使用例については、if __name__=="__main__"ブロックを参照してください。秘訣は、グループIDのリストを使用しての値をグループ化するtことです。このIDリストの長さは、少なくとも。の長さと同じである必要がありtます。

主な概念のみを説明します。何もわからない場合は、質問してください。

groupbyitertoolsから使用します。ここでの使い方は簡単ではないかもしれませんが、すぐに理解できると思います。

関数としてkey、ファクトリ関数を介して動的に作成するメソッドを使用します。ここでの主なコンセプトは「クロージャ」です。グループIDのリストは、内部関数に「アタッチ」されていますget_group。したがって:

  • このリストは、への各呼び出しに固有extract_groups_from_iterableです。複数回使用でき、グローバルは使用されません

  • このリストの状態は、の同じインスタンスへの後続の呼び出し間で共有されますget_group(関数もオブジェクトであることに注意してください!したがってget_group、スクリプトの実行中に2つのインスタンスがあります。

これに加えて、によって返されるグループからリストまたはスカラーを作成する簡単な方法がありますgroupby

それでおしまい。

from itertools import groupby

def extract_groups_from_iterable(iterable, group_ids):
    return [_make_list_or_scalar(g) for k, g in 
                        groupby(iterable, _get_group_id_provider(group_ids))
           ]

def _get_group_id_provider(group_ids):
    def get_group(value, group_ids = group_ids):
        return group_ids.pop(0)
    return get_group

def _make_list_or_scalar(iterable):
    list_ = list(iterable)
    return list_ if len(list_) != 1 else list_[0]

if __name__ == "__main__":
    t1 = range(9)
    group_ids1 = [1,2,3,4,5,5,6,7,8]
    a,b,c,d,e,f,g,h = extract_groups_from_iterable(t1, group_ids1)

    for varname in "abcdefgh":
        print varname, globals()[varname]

    print

    t2 = range(15)
    group_ids2 = [1,2,2,3,4,5,5,5,5,5,6,6,6,7,8]
    a,b,c,d,e,f,g,h = extract_groups_from_iterable(t2, group_ids2)

    for varname in "abcdefgh":
        print varname, globals()[varname]

出力は次のとおりです。

a 0
b 1
c 2
d 3
e [4, 5]
f 6
g 7
h 8

a 0
b [1, 2]
c 3
d 4
e [5, 6, 7, 8, 9]
f [10, 11, 12]
g 13
h 14

繰り返しになりますが、これはやり過ぎのように思えるかもしれませんが、これがコードの削減に役立つ場合は、それを使用してください。

于 2013-02-07T15:49:34.733 に答える
0

タプルをスライスしてみませんか?

t = tuple(float(x) for x in line.split())
c = t[2:5]  #maybe t[2:-4] instead?
f = t[-2:]

デモ:

>>> line = "1 2 3 4 5 6 7 8 9"
>>> t = tuple(float(x) for x in line.split())
>>> c = t[2:5]  #maybe t[2:-4] instead?
>>> f = t[-2:]
>>> c
(3.0, 4.0, 5.0)
>>> t
(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
>>> c = t[2:-4]
>>> c
(3.0, 4.0, 5.0)

pythonicであるというトピックに取り組んでいますが、文字列はどこにあるのか、line.strip().split()いつでも安全に記述できます。 引数を指定しないと、空白が削除されます。line.split()linesplit

于 2013-02-07T14:54:55.683 に答える