簡體   English   中英

獲取 map() 以返回 Python 3.x 中的列表

[英]Getting a map() to return a list in Python 3.x

我正在嘗試將 map 列表轉換為十六進制,然后在其他地方使用該列表。 在 python 2.6 中,這很容易:

答: Python 2.6:

>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']

但是,在 Python 3.1 中,上述返回 map object。

B: Python 3.1:

>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>

如何檢索 Python 3.x 上的映射列表(如上圖A )?

或者,有沒有更好的方法來做到這一點? 我的初始列表 object 有大約 45 個項目,我喜歡將它們轉換為十六進制。

做這個:

list(map(chr,[66,53,0,94]))

在 Python 3+ 中,許多迭代可迭代對象的進程本身返回迭代器。 在大多數情況下,這最終會節省內存,並且應該讓事情變得更快。

如果您要做的只是最終迭代此列表,則甚至無需將其轉換為列表,因為您仍然可以像這樣迭代map對象:

# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
    print(ch)

Python 3.5 中的新功能:

[*map(chr, [66, 53, 0, 94])]

感謝額外的解包概括

更新

一直在尋找更短的方法,我發現這個方法也有效:

*map(chr, [66, 53, 0, 94]),

解包也適用於元組。 注意最后的逗號。 這使它成為 1 個元素的元組。 也就是說,它等價於(*map(chr, [66, 53, 0, 94]),)

它比帶有列表括號的版本短了一個字符,但是,在我看來,最好寫,因為你從星號開始——擴展語法,所以我覺得它更柔軟。 :)

你為什么不這樣做:

[chr(x) for x in [66,53,0,94]]

它被稱為列表理解。 您可以在 Google 上找到大量信息,但這里是列表推導上 Python (2.6) 文檔的鏈接 不過,您可能對 Python 3 文檔更感興趣。

返回列表的地圖功能具有節省打字的優勢,尤其是在交互式會話期間。 您可以定義返回列表的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創建類似的功能。

對原始問題有評論:

我建議重命名為 Getting map() 以在 Python 3.* 中返回一個列表,因為它適用於所有 Python3 版本。 有沒有辦法做到這一點? – 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]]

轉換我的舊評論以獲得更好的可見性:對於完全不使用map的“更好的方法”,如果您的輸入已知是 ASCII 序數,則轉換為bytes和解碼通常要快得多,例如bytes(list_of_ordinals).decode('ascii') 這為您提供了一個str值,但如果您需要一個可變性list等,您可以轉換它(而且它仍然更快)。 例如,在ipython microbenchmarks 中轉換 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%。 通過bytesbytes.decode進行批量轉換,然后批量轉換回list可以節省大量工作,如前所述,僅當您的所有輸入都是 ASCII 序數(或每個字符區域設置特定編碼的某個字節中的序數,例如latin-1 )時才有效)。

list(map(chr, [66, 53, 0, 94]))

map(func, *iterables) --> map object 創建一個迭代器,使用每個可迭代對象的參數計算函數。 當最短的迭代用完時停止。

“做一個迭代器”

意味着它將返回一個迭代器。

“使用來自每個可迭代對象的參數計算函數”

意味着迭代器的 next() 函數將獲取每個可迭代對象的一個​​值,並將它們中的每一個傳遞給函數的一個位置參數。

所以你從 map() 函數中得到一個迭代器,然后將它傳遞給 list() 內置函數或使用列表推導。

除了Python 3中的上述答案之外,我們還可以簡單地從map中創建一個結果值list

li = []
for x in map(chr,[66,53,0,94]):
    li.append(x)

print (li)
>>>['B', '5', '\x00', '^']

我們可以通過另一個讓我印象深刻的例子來概括,map 上的操作也可以像regex問題一樣以類似的方式處理,我們可以編寫函數來獲取要映射的項目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 中的列表理解和基本的 map 函數實用程序,也可以這樣做:

chi = [x for x in map(chr,[66,53,0,94])]

您可以嘗試通過迭代對象中的每個項目並將其存儲在不同的變量中來從地圖對象中獲取列表。

a = map(chr, [66, 53, 0, 94])
b = [item for item in a]
print(b)
>>>['B', '5', '\x00', '^']

另一種選擇是創建一個快捷方式,返回一個列表:

from functools import reduce
_compose = lambda f, g: lambda *args: f(g(*args))
lmap = reduce(_compose, (list, map))

>>> lmap(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']

在 pyton3.X 中執行此操作的最佳方法

簡單地說,你可以在單行中做到這一點

#Devil
input_list = [66, 53, 0, 94]
out = [chr(x) for x in input_list]
print(out)

# you will get the desire output in out list
# ['B', '5', '\x00', '^']

#------------------------------
#To retrieve your list use 'ord'

original_list = [ord(x) for x in out]
print(original_list )
#[66, 53, 0, 94]

在Python 3中,地圖,過濾器等的功能已更改。 它不會返回列表,而是返回一個迭代器,我們可以對其進行迭代。 因此,在您的情況下,迭代器是map對象。 因此就做

lst = [value for value in map(chr, [66, 53, 0, 94])]

這應該很好

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM