5

私は Python 初心者で、ネストされたリスト内包表記を理解するのに苦労しています。ファイルを読み取り、各行の各文字のリストを作成するコードを作成しようとしています。

したがって、ファイルに含まれている場合

xxxcd
cdcdjkhjasld
asdasdxasda

結果のリストは次のようになります。

[
['x','x','x','c','d']
['c','d','c','d','j','k','h' ,'j','a','s','l','d']
['a','s','d','a','s','d','x', 'a','s','d','a']
]

私は次のコードを書きましたが、それは機能しますが、より少ないコード行でこれを行うには、ネストされたリスト内包表記を記述できるはずだとしつこく感じています。任意の提案をいただければ幸いです。

data = []
f = open(file,'r')
for line in f:
    line = line.strip().upper()
    list = []
    for c in line:
        list.append(c)
    data.append(list)
4

7 に答える 7

19

これが役立つはずです(おそらく、改行を削除したり、必要に応じてフォーマットしたりするために、いじる必要がありますが、基本的な考え方はうまくいくはずです):

f = open(r"temp.txt")
[[c for c in line] for line in f]
于 2009-12-30T20:06:25.653 に答える
3

あなたの場合、listコンストラクターを使用して内側のループを処理し、外側のループにリスト内包表記を使用できます。何かのようなもの:

f = open(file)
data = [list(line.strip().upper()) for line in f]

文字列を入力として指定すると、リスト コンストラクターは、文字列の各文字がリスト内の 1 つの要素であるリストを作成します。

リスト内包表記は、機能的には次のものと同等です。

data = []
for line in f:
    data.append(list(line.strip().upper()))
于 2009-12-30T20:07:41.017 に答える
2

これは、リスト理解の 1 つのレベルです。

data = []
f = open(file,'r')

for line in f:
    data.append([ch for ch in line.strip().upper()])

しかし、すべてを一度に行うことができます。

f = open(file, 'rt')
data = [list(line.strip().upper()) for line in f]

これはlist()、文字列を単一文字列のリストに変換するために使用しています。ネストされたリスト内包表記を使用して、open()インラインに配置することもできます。

data = [[ch for ch in line.strip().upper()] for line in open(file, 'rt')]

ただし、この時点では、リスト内包表記が何が起こっているのかを読みやすくすることを妨げていると思います。

リスト内のリストなどの複雑な処理ではfor、外側の層にループを使用し、内側のループにリスト内包表記を使用することができます。

また、Chris Lutz がコメントで述べたように、この場合、各行を明示的に文字リストに分割する理由は実際にはありません。常に文字列をリストとして扱うことができ、文字列で文字列メソッドを使用できますが、リストで文字列メソッドを使用することはできません。(まあ、リストを文字列に再結合するために使用できますが''.join()、文字列のままにしておかないのはなぜですか?)

于 2009-12-30T20:05:54.750 に答える
1

文字列と文字のリストの唯一の本当に重要な違いは、文字列が不変であるということです。リストと同じように、文字列を繰り返してスライスすることができます。また、文字列は文字列メソッドをサポートし、リストはサポートしないため、文字列を文字列として処理する方がはるかに便利です。

dataしたがって、ほとんどのアプリケーションでは、アイテムをリストに変換する必要はありません。私はただするだろう:

data = [line.strip() for line in open(filename, 'r')]

data文字列を可変リストとして操作する必要がある場合は、文字列listを変換しjoinて元に戻すために使用します。例:

data[2] = ''.join(sorted(list(data[2])))

もちろん、これらの文字列を変更するだけの場合は、先に進んでリストとして保存してください。

于 2009-12-30T20:29:54.950 に答える
1
data = [list(line.strip().upper()) for line in open(file,'r')]
于 2009-12-30T20:05:38.717 に答える
0

まず、次のように、 line.strip().upper() 部分を外側の for ループと組み合わせることができます。

for line in [l.strip().upper() for l in f]:
    # do stuff

次に、文字の反復をリスト内包表記にすることができますが、それは短くも明確にもなりません。そこで行うことを行うための最もきちんとした方法は次のとおりです。

list(someString)

したがって、次のことができます。

data = [list(l.strip().upper()) for l in f]

それがあなたの意図をうまく表しているかどうかはわかりません。エラー処理も問題です。途中で問題が発生すると、式全体が死んでしまいます。


ファイル全体とすべての行をメモリに保存する必要がない場合は、それをジェネレータ式にすることができます。これは、巨大なファイルを処理するときに非常に便利で、一度にチャンクを処理するだけで済みます。ジェネレータ式では、次のように代わりに括弧を使用します。

data = (list(l.strip().upper()) for l in f)

dataファイル内の各行の式を実行するジェネレーターになりますが、それを反復する場合のみです。それを、メモリ内に巨大なリストを作成するリスト内包表記と比較してください。dataはリストではなくジェネレータであり、C++ のイテレータまたは C# の IEnumerator に似ていることに注意してください。

ジェネレーターは簡単にリストに入れることができます:list(someGenerator)それは目的を幾分無効にしますが、時には必要です。

于 2009-12-30T20:06:33.173 に答える
0
>>> f = file('teste.txt')
>>> print map(lambda x: [c for c in x][:-1], f)
[['x', 'x', 'x', 'c', 'd'], ['c', 'd', 'c', 'd', 'j', 'k', 'h', 'j', 'a', 's', 'l', 'd'], ['a', 's', 'd', 'a', 's', 'd', 'x', 'a', 's', 'd']]
于 2009-12-30T20:07:33.560 に答える