Python 3.x에서 목록을 반환하기 위해 map () 가져 오기


523

목록을 16 진수로 매핑 한 다음 다른 곳에서 목록을 사용하려고합니다. 파이썬 2.6에서는 이것이 쉬웠다.

A : 파이썬 2.6 :

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

그러나 Python 3.1에서는 위의 맵 객체가 반환됩니다.

B : 파이썬 3.1 :

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

A 에서와 같이 매핑 된 목록을 검색하는 방법 파이썬 3.x의에서 이상)?

또는이 작업을 수행하는 더 좋은 방법이 있습니까? 내 초기 목록 객체에는 약 45 개의 항목이 있으며 ID는 16 진수로 변환하고 싶습니다.


2
리스트 이해 를 사용하는 것이 더 pythonic 입니다. map()거의 언어에서 제거 지능형리스트 나에 그것을 사용할 필요가 없기 때문에 for루프.
Boris

답변:


771

이 작업을 수행:

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

Python 3 이상에서는 반복 가능 항목을 반복하는 많은 프로세스가 반복자 자체를 반환합니다. 대부분의 경우 메모리가 절약되어 작업 속도가 빨라집니다.

이 목록을 결국 반복하는 것만으로도 목록을 변환 할 필요가 없습니다. map객체를 다음과 같이 반복 할 수 있기 때문입니다 .

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

15
물론, 이것에 대해서도 반복 할 수 있습니다 : ([65,66,67,68]에서 x에 대한 chr (x)). 지도가 필요하지 않습니다.
hughdbrown

2
@hughdbrown 3.1을 사용하는 주장 map은 복잡한 함수, 큰 데이터 세트 또는 스트림에서 반복 할 때 게으른 평가입니다.
앤드류 키튼

18
@Andrew는 실제로 휴가 동일한 작업을 수행 할 수있는 제너레이터 이해력을 사용하고 있습니다. 대괄호가 아닌 괄호에 유의하십시오.
Triptych

5
값이 ASCII / latin-1 인 것으로 알려진 경우 대체 솔루션 (대량 입력의 경우도 빠름)은 C 계층에서 대량 변환을 수행 bytes(sequence_of_ints_in_range_0_to_256).decode('latin-1')하는 str것입니다. C 레벨 함수 호출 만 사용하는 모든 요소 개별 문자 list가 실제로 필요한 경우 위의 내용을 래핑 할 수 list있지만 str이미 자체 문자를 반복 할 수 있기 때문에 변경이 필요한 유일한 이유입니다.
ShadowRanger

1
list (map (str, [1,2,3]))은 CentOS 7에서 Python 3.4.3에 대해 "인수 오류"를 제공합니다. 목록 이해 기능이 작동합니다.
Andor

108

Python 3.5의 새롭고 깔끔한 기능 :

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

추가적인 포장 풀기 일반화 덕분에

최신 정보

항상 더 짧은 길을 찾고 있는데, 이것도 효과가 있습니다.

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

포장 풀기는 튜플에서도 작동합니다. 끝에 쉼표를 적어 둡니다. 이것은 1 요소의 튜플을 만듭니다. 즉,(*map(chr, [66, 53, 0, 94]),)

목록 대괄호가있는 버전의 문자 하나만 짧아 지지만 내 의견으로는 별표 (확장 구문)로 시작하기 때문에 작성하는 것이 좋습니다. 그래서 마음이 부드럽습니다. :)


11
@Quelklef list()는 깔끔하게 보이지 않습니다
Arijoon

5
@Quelklef : 또한 list생성자 를 찾고 일반 함수 호출 기계를 호출 할 필요가 없기 때문에 언 패킹 접근 방식이 매우 빠릅니다 . 긴 입력의 경우 중요하지 않습니다. 짧은 경우 큰 차이를 만들 수 있습니다. 입력과 함께 위 코드를 tuple반복해서 재구성하지 않는 ipython마이크로 벤치 마크는 list()래핑 방식이 언 패킹보다 약 20 % 더 오래 걸린다는 것을 보여줍니다 . 절대적으로, 우리는 150 ns에 대해 이야기하고 있습니다. 사소한 것이지만 아이디어를 얻습니다.
ShadowRanger

오래된 문제가 무엇입니까 map? lmap새로운 기본값이 반복자를 반환하는 경우 새로운 이름 ( ?)이 있습니까?
Giorgio

1
*map()에 구문 오류가 있습니다 Python 3.6: can't use starred expression here. 당신은 그것을 넣어야합니다 list:[ *map() ]
ALH

4
@ALH 명령 끝에 쉼표가 없습니다. 쉬운 실수!
LondonRob 2012 년

103

왜 이러지 않습니까?

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

이것을 목록 이해력이라고합니다. Google에서 많은 정보를 찾을 수 있지만 다음은 목록 이해에 대한 Python (2.6) 문서에 대한 링크 입니다. 그러나 Python 3 문서 에 더 관심이있을 수 있습니다 .


4
흠. 어쩌면 목록 이해, 생성기, map (), zip () 및 파이썬의 다른 빠른 반복 우수성에 대한 일반적인 게시가 필요할 수 있습니다.
hughdbrown

46
좀 더 장황하기 때문에 추가 변수를 작성해야합니다 (두 번) ... 연산이 더 복잡하고 람다를 작성하게되거나 일부 요소를 삭제 해야하는 경우, 이해력이 결정적으로 더 좋다고 생각합니다 지도 + 필터보다 이미 적용하려는 기능이 있으면지도가 더 간결 해집니다.
포트란

1
+1 : 읽기 쉽고 더 많은 파라미터를 가진 기능을 사용할 수 있습니다
Le Droid

7
map(chr, [66,53,0,94])보다 간결합니다 [chr(x) for x in [66,53,0,94]].
Giorgio

다른 답변보다 훨씬 빠름
Evhz

25

목록 리턴 맵 기능은 특히 대화식 세션에서 타이핑을 저장하는 이점이 있습니다. list를 반환 하는 lmap함수 (python2와 유사)를 정의 할 수 있습니다 imap.

lmap = lambda func, *iterable: list(map(func, *iterable))

그런 다음 lmap대신 호출 map하면 작업이 수행 lmap(str, x)됩니다. 5 자 (이 경우 30 %)보다 list(map(str, x))짧고 확실히 짧습니다 [str(v) for v in x]. 비슷한 기능을 만들 수도 있습니다 filter.

원래 질문에 대한 의견이있었습니다.

모든 Python3 버전에 적용되므로 Python 3. *에서 목록을 반환하도록 Getting map ()으로 이름을 바꾸는 것이 좋습니다. 이 방법이 있습니까? – 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

4

가시성을 높이기 위해 이전 주석 을 변환 : map입력이 ASCII 서수라고 알려진 경우 전체적으로 "이를 수행하는 더 좋은 방법"을 얻으 려면 일반적으로 bytesla 로 변환 하고 디코딩하는 것이 훨씬 빠릅니다 bytes(list_of_ordinals).decode('ascii'). 그것은 당신에게 str값을 가져다 주지만, 변경 list가능성 등 이 필요하다면, 그것을 변환 할 수 있습니다 (그리고 여전히 더 빠릅니다). 예를 들어 ipython45 개의 입력을 변환 하는 마이크로 벤치 마크 에서 :

>>> %%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 서수 (또는 문자 로케일 별 인코딩 (예 :) 당 1 바이트의 서수) 인 경우에만 작동합니다 latin-1.


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

map (func, * iterables)-> map 객체 각 iterables의 인수를 사용하여 함수를 계산하는 반복자를 만듭니다. 가장 짧은 iterable이 소진되면 중지합니다.

"반복자 만들기"

반복자를 반환한다는 의미입니다.

"각 iterables의 인수를 사용하여 함수를 계산합니다."

iterator의 next () 함수는 각 iterables의 값 하나를 가져 와서 함수의 위치 매개 변수 하나에 전달합니다.

따라서 map () 함수에서 반복자를 가져오고 jsut은 list () 내장 함수에 전달하거나 목록 이해를 사용합니다.


2

의 위의 답변 외에도 as 에서 결과 값을 Python 3만들 수 있습니다.listmap

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

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

우리는 내가 맞은 또 다른 예를 통해 일반화 할 수 있습니다.지도상의 작업도 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]

@miradulo 파이썬 2에서는 목록이 반환되었지만 파이썬 3에서는 유형 만 반환되고 동일한 형식으로 제공하려고했습니다. 당신이 불필요하다고 생각한다면, 나와 같은 사람들이 유용하다고 생각하는 사람들이있을 수 있습니다.
Harry_pb

2
목록 이해, 목록 함수 및 압축 풀기 응답이 이미있는 경우 명시 적 for 루프는 많은 IMHO를 추가하지 않습니다.
miradulo

1

객체의 각 항목을 반복하고 다른 변수에 저장하여지도 객체에서 목록을 가져올 수 있습니다.

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

0

파이썬에서 목록 이해와 기본 맵 함수 유틸리티를 사용하여 다음을 수행 할 수도 있습니다.

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


chi리스트는 주어진 요소의 ASIC 값을 포함합니다.
darshan ks
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.