リストを16進数にマップしてから、そのリストを別の場所で使用しようとしています。 Python 2.6では、これは簡単でした。
A: / Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
しかし、Python 3.1では、上記はmapオブジェクトを返します。
B: / Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Python 3.xで(上の _ a _ のように)マップされたリストを取得するにはどうすればいいですか?
あるいは、これを行うより良い方法はありますか?私の最初のリストオブジェクトはおよそ45のアイテムを持っていて、それらを16進数に変換するのが好きです。
これを行う:
list(map(chr,[66,53,0,94]))
Python 3+では、イテラブルをイテレートする多くのプロセスはそれ自身イテレータを返します。ほとんどの場合、これはメモリを節約することになり、物事はより速く進むでしょう。
このリストを最終的に反復するだけでいいのであれば、リストに変換する必要さえありません。これは、map
オブジェクトを反復することができるためです。
# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
print(ch)
なぜあなたはこれをやっていません:
[chr(x) for x in [66,53,0,94]]
これはリスト内包表記と呼ばれます。 Googleにはたくさんの情報がありますが、 リストの内包表記に関するPython(2.6)ドキュメントへのリンクです 。 Python 3のドキュメント にもっと興味があるかもしれません。
Python 3.5の新機能
[*map(chr, [66, 53, 0, 94])]
おかげで その他の開梱一般化
_ update _
常に短い方法を模索していますが、私はこれもうまくいくことを発見しました。
*map(chr, [66, 53, 0, 94]),
解凍はタプルでも機能します。末尾のコンマに注意してください。これはそれを1要素のタプルにします。つまり、(*map(chr, [66, 53, 0, 94]),)
と同等です。
リストの括弧で囲まれたバージョンから1文字だけ短くなりますが、私の考えでは、アスタリスク - 展開構文 - から始めることをお勧めしますので、私は頭が柔らかいと思います。 :)
リストを返すマップ機能には、特に対話型セッション中に入力を節約できるという利点があります。 listを返すlmap
関数を(python2のimap
と同様に)定義することができます。
lmap = lambda func, *iterable: list(map(func, *iterable))
lmap
の代わりにmap
を呼び出すと、次のようになります。lmap(str, x)
はlist(map(str, x))
より5文字短く(この場合は30%)、確かに[str(v) for v in x]
より短くなります。 filter
に対しても同様の関数を作成することができます。
元の質問にコメントがありました。
私はPython 3 *でリストを返すようにGetting map()に改名することをお勧めします。*それはすべてのPython 3バージョンに適用されるので。これを行う方法はありますか? - meawoppl 1月24日17時58分
それをすることは は 可能ですが、それは非常に悪い考えです。楽しみのためだけに、ここにあなたがどのように( するべきではない )すべきかを示します。
__global_map = map #keep reference to the original map
lmap = lambda func, *iterable: list(__global_map(func, *iterable)) # using "map" here will cause infinite recursion
map = lmap
x = [1, 2, 3]
map(str, x) #test
map = __global_map #restore the original map and don't do that again
map(str, x) #iterator
私はPython 3.1に慣れていませんが、これでうまくいくでしょうか。
[chr(x) for x in [66, 53, 0, 94]]
変換 my old comment 視認性を向上させる:map
を完全に使用しない「これを行うためのより良い方法」のために、入力がASCII序数であることがわかっている場合、それは一般にbytes
に変換してデコードするには、bytes(list_of_ordinals).decode('ascii')
のようにはるかに高速です。これにより、値のstr
が取得されますが、可変性などのためにlist
が必要な場合は、それを変換できます(それでも高速です)。たとえば、ipython
の45個の入力を変換するマイクロベンチマークでは:
>>> %%timeit -r5 ordinals = list(range(45))
... list(map(chr, ordinals))
...
3.91 µs ± 60.2 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)
>>> %%timeit -r5 ordinals = list(range(45))
... [*map(chr, ordinals)]
...
3.84 µs ± 219 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)
>>> %%timeit -r5 ordinals = list(range(45))
... [*bytes(ordinals).decode('ascii')]
...
1.43 µs ± 49.7 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)
>>> %%timeit -r5 ordinals = list(range(45))
... bytes(ordinals).decode('ascii')
...
781 ns ± 15.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)
str
のままにしておくと、最速のmap
ソリューションの約20%の時間がかかります。リストに変換し直しても、最速のmap
ソリューションの40%未満です。 bytes
およびbytes.decode
を介して一括変換すると、list
に一括変換して多くの作業を節約できます。butすべての入力がASCII序数(または文字ロケール固有のエンコーディングごとに1バイトの序数、たとえばlatin-1
)の場合にのみ機能します。
list(map(chr, [66, 53, 0, 94]))
map(func、* iterables) - > map object各イテラブルからの引数を使って関数を計算するイテレータを作る。最短の反復可能オブジェクトが使い果たされると停止します。
"イテレータを作る"
イテレータを返すことを意味します。
「各イテラブルからの引数を使用して関数を計算します」
これは、イテレータのnext()関数が各イテラブルの1つの値を取り、それらのそれぞれを関数の1つの位置パラメータに渡すことを意味します。
そのため、map()関数からイテレータを取得し、それをlist()組み込み関数に渡すか、リスト内包表記を使用します。
上記のPython 3
の回答に加えて、以下のようにlist
から結果値のmap
を作成することもできます。
li = []
for x in map(chr,[66,53,0,94]):
li.append(x)
print (li)
>>>['B', '5', '\x00', '^']
別の例によって説明すると、regex
問題のようにmapに対する操作も同様に扱うことができます。mapする項目のlist
を取得する関数を記述して同時に結果セットを取得できます。例.
b = 'Strings: 1,072, Another String: 474 '
li = []
for x in map(int,map(int, re.findall('\d+', b))):
li.append(x)
print (li)
>>>[1, 72, 474]
Pythonのリスト内包表記と基本的なマップ関数ユーティリティを使用して、これを行うこともできます。
chi = [x for x in map(chr,[66,53,0,94])]