28

次のような2Dリストがあります。

table = [['donkey', '2', '1', '0'], ['goat', '5', '3', '2']]

最後の3つの要素を整数に変更したいのですが、以下のコードは非常に醜い感じがします。

for row in table:
    for i in range(len(row)-1):
        row[i+1] = int(row[i+1])

しかし、私はむしろ次のようなものが欲しいです:

for row in table:
    for col in row[1:]:
        col = int(col)

上記のコードを書く方法があるはずですが、スライスは元のリストとは別のイテレーター/新しいリストを作成するため、参照は引き継がれません。

よりPythonicなソリューションを取得する方法はありますか?

4

7 に答える 7

20
for row in table:
    row[1:] = [int(c) for c in row[1:]]

上記はよりPythonicに見えますか?

于 2011-04-15T04:36:08.210 に答える
13

試す:

>>> for row in table:
...     row[1:]=map(int,row[1:])
... 
>>> table
[['donkey', 2, 1, 0], ['goat', 5, 3, 2]]

AFAIK、listスライスに割り当てると、新しいを作成する代わりに、操作が強制的に実行されますlist

于 2011-04-15T04:29:14.690 に答える
8

私はシェカールの答えがとても好きです。

原則として、Pythonコードを作成するときに、for i in range(len(somelist))を作成していることに気付いた場合は、間違っています。

  • enumerateリストが1つしかない場合は試してください
  • 試してみるzipitertools.izip、並行して繰り返したいリストが2つ以上ある場合

あなたの場合、最初の列が異なるため、列挙型をエレガントに使用することはできません。

for row in table:
    for i, val in enumerate(row):
        if i == 0: continue
        row[i] = int(val)
于 2011-04-15T06:40:41.773 に答える
3

「醜い」コードはrange、次の2つの引数を指定して呼び出すだけで改善できます。

for row in table:
    for i in range(1, len(row)):
        row[i] = int(row[i])

mapこれは、新しい一時リストを割り当てずに(リスト内包、、、および/またはスライスを使用して)アイテムを所定の位置に変更することを主張する場合に、おそらく最善の方法です。Pythonの「map」に相当するインプレースはありますか?を参照してください。

推奨しませんが、独自のインプレースマップ関数を導入することで、このコードをより一般的にすることもできます。

def inplacemap(f, items, start=0, end=None):
    """Applies ``f`` to each item in the iterable ``items`` between the range
    ``start`` and ``end``."""
    # If end was not specified, make it the length of the iterable
    # We avoid setting end in the parameter list to force it to be evaluated on
    # each invocation
    if end is None:
        end = len(items)
    for i in range(start, end):
        items[i] = f(items[i])

for row in table:
    inplacemap(int, row, 1)

個人的には、これはPythonicではないと思います。それを行うための明白な方法は1つだけであることが望ましく、これはそうではありません。

于 2011-04-15T04:28:38.283 に答える
1

リスト内包表記を使用する:

table = [row[0] + [int(col) for col in row[1:]] for row in table]
于 2011-04-15T04:28:09.173 に答える
0

これは機能します:

table = [[row[0]] + [int(v) for v in row[1:]] for row in table]

ただし、リストが最初に作成された時点で変換を行うことを検討することをお勧めします。

于 2011-04-15T04:38:14.150 に答える
-1

これはあなたが探しているものを達成します。これは読みやすいソリューションです。listcompを使用して同様のものを探すこともできます。

>>> for row in table:
...     for i, elem in enumerate(row):
...             try:
...                     int(elem)
...             except ValueError:
...                     pass
...             else:
...                     row[i] = int(elem)
... 
于 2011-04-15T04:29:14.607 に答える