リストのリストから各サブリストの最初の項目を抽出し、それを新しいリストに追加するための最善の方法は何でしょうか。私が持っているのであれば:
lst = [[a,b,c], [1,2,3], [x,y,z]]
a
、1
、x
を取り出して、それらとは別のリストを作成したいと思います。
私は試した:
lst2.append(x[0] for x in lst)
>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [item[0] for item in lst]
>>> lst2
['a', 1, 'x']
あなたはZipを使用することができます:
>>> lst=[[1,2,3],[11,12,13],[21,22,23]]
>>> Zip(*lst)[0]
(1, 11, 21)
あるいは、Zip
がリストを生成しないPython 3:
>>> list(Zip(*lst))[0]
(1, 11, 21)
または、
>>> next(Zip(*lst))
(1, 11, 21)
または、(私のお気に入り)numpyを使用してください。
>>> import numpy as np
>>> a=np.array([[1,2,3],[11,12,13],[21,22,23]])
>>> a
array([[ 1, 2, 3],
[11, 12, 13],
[21, 22, 23]])
>>> a[:,0]
array([ 1, 11, 21])
Pythonには、リスト内の特定のインデックスにある項目を返すためのitemgetterという関数があります。
from operator import itemgetter
Itemgetter()関数に、取得したい項目のインデックスを渡します。最初のアイテムを取得するには、itemgetter(0)を使います。理解しておくべき重要なことは、itemgetter(0)自体が関数を返すということです。その関数にリストを渡すと、特定の項目が得られます。
itemgetter(0)([10, 20, 30]) # Returns 10
これは、最初の引数として関数を、2番目の引数としてリスト(またはその他の反復可能なもの)をとるmap()と組み合わせると便利です。それはイテラブルの各オブジェクトで関数を呼び出した結果を返します。
my_list = [['a', 'b', 'c'], [1, 2, 3], ['x', 'y', 'z']]
list(map(itemgetter(0), my_list)) # Returns ['a', 1, 'x']
Map()はジェネレータを返すので、実際のリストを取得するために結果はlist()に渡されます。要約すると、あなたの仕事はこのようにすることができます:
lst2.append(list(map(itemgetter(0), lst)))
これはリスト内包表記を使用する代わりの方法であり、どの方法を選択するかは、コンテキスト、読みやすさ、および好みによって大きく異なります。
詳細情報: https://docs.python.org/3/library/operator.html#operator.itemgetter
同じ問題を抱えていて、各ソリューションのパフォーマンスについて興味を持った。
これが%timeit
です:
import numpy as np
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
配列を変換する最初のでこぼこした方法:
%timeit list(np.array(lst).T[0])
4.9 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
リスト内包表記を使った完全ネイティブ(@alecxeで説明されているように):
%timeit [item[0] for item in lst]
379 ns ± 23.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Zip
を使用する別のネイティブな方法(@dawgで説明されているように):
%timeit list(Zip(*lst))[0]
585 ns ± 7.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
第二の厄介な方法。 @dawg氏による説明もあります。
%timeit list(np.array(lst)[:,0])
4.95 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
驚いたことに(少なくとも私にとっては)リスト内包表記を使用するネイティブの方法は、ぎこちない方法よりも最速で約10倍高速です。最後のlist
を使わずに2つの厄介な方法を実行すると、約1 µs節約できますが、それでも10倍の差があります。
各コードスニペットをlen
への呼び出しで囲んだときに、ジェネレータが最後まで実行されるようにするために、タイミングは同じままでした。
あなたのコードはほぼ正しいです。唯一の問題はリスト内包表記の使い方です。
Like:(lstのxのx [0])を使用すると、ジェネレータオブジェクトが返されます。 like:[x [0] for lst]を使うと、リストが返されます。
リスト内包表記の出力をリストに追加すると、リスト内包表記の出力はリストの単一要素になります。
lst = [["a","b","c"], [1,2,3], ["x","y","z"]]
lst2 = []
lst2.append([x[0] for x in lst])
print lst2[0]
lst2 = [['a'、1、 'x']]
lst2 [0] = ['a'、1、 'x']
私が間違っているかどうか私に知らせてください。
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
outputlist = []
for values in lst:
outputlist.append(values[0])
print(outputlist)
出力:['a', 1, 'x']
あなたはあなたが既存のリストを持っていると言った。だから私はそれで行きます。
>>> lst1 = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [1, 2, 3]
今、あなたはジェネレータオブジェクトを2番目のリストに追加しています。
>>> lst2.append(item[0] for item in lst)
>>> lst2
[1, 2, 3, <generator object <genexpr> at 0xb74b3554>]
しかし、おそらくあなたはそれを最初の項目のリストにしたいでしょう。
>>> lst2.append([item[0] for item in lst])
>>> lst2
[1, 2, 3, ['a', 1, 'x']]
最初の項目のリストを既存のリストに追加しました。アイテムのリストではなく、アイテムのテーマ自体を既存のものに追加したい場合は、list.extendを使用します。その場合私たちはジェネレータを追加することを心配する必要はありません、extendは現在のリストを拡張するためにそこから取得したそれぞれの項目を追加するためにそのジェネレータを使います。
>>> lst2.extend(item[0] for item in lst)
>>> lst2
[1, 2, 3, 'a', 1, 'x']
または
>>> lst2 + [x[0] for x in lst]
[1, 2, 3, 'a', 1, 'x']
>>> lst2
[1, 2, 3]
https://docs.python.org/3.4/tutorial/datastructures.html#more-on-listshttps://docs.python.org/3.4/tutorial/datastructures.html#list-comprehensions