[python] 중첩 된 목록에 대한 목록 이해?

이 중첩 목록이 있습니다.

l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

이제하고 싶은 것은 목록의 각 요소를 부동으로 변환하는 것입니다. 내 해결책은 이것입니다 :

newList = []
for x in l:
  for y in x:
    newList.append(float(y))

그러나 이것은 중첩 된 목록 이해를 사용하여 수행 할 수 있습니까?

내가 한 일은 :

[float(y) for y in x for x in l]

그러나 결과는 2400의 합계로 100의 무리입니다.

어떤 해결책이든, 설명은 대단히 감사하겠습니다. 감사!



답변

중첩 된 목록 이해로이를 수행하는 방법은 다음과 같습니다.

[[float(y) for y in x] for x in l]

이렇게하면 문자열 대신 부동 소수점을 제외하고 시작한 것과 비슷한 목록 목록이 제공됩니다. 하나의 플랫 목록을 원하면을 사용 [float(y) for x in l for y in x]합니다.


답변

다음은 중첩 for 루프를 중첩 목록 이해로 변환하는 방법입니다.

여기에 이미지 설명을 입력하십시오

중첩 된 목록 이해는 다음과 같습니다.

            l a b c d e f
                  
In [1]: l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
In [2]: for a in l:
   ...:     for b in a:
   ...:         for c in b:
   ...:             for d in c:
   ...:                 for e in d:
   ...:                     for f in e:
   ...:                         print(float(f))
   ...:
1.0

In [3]: [float(f)
         for a in l
   ...:     for b in a
   ...:         for c in b
   ...:             for d in c
   ...:                 for e in d
   ...:                     for f in e]
Out[3]: [1.0]

귀하의 경우에는 다음과 같습니다.

In [4]: new_list = [float(y) for x in l for y in x]


답변

>>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> new_list = [float(x) for xs in l for x in xs]
>>> new_list
[40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]


답변

원하는 출력이 무엇인지 모르지만 목록 이해를 사용하는 경우 순서는 중첩 루프의 순서를 따릅니다. 그래서 나는 당신이 원하는 것을 얻었습니다.

[float(y) for x in l for y in x]

원칙은 : 중첩 된 for 루프로 작성할 때와 같은 순서를 사용하는 것입니다.


답변

여기에 조금 늦었지만 실제로 목록 이해가 특히 중첩 된 목록 이해가 어떻게 작동하는지 공유하고 싶었습니다.

New_list= [[float(y) for x in l]

실제로는 다음과 같습니다.

New_list=[]
for x in l:
    New_list.append(x)

그리고 이제 중첩 된 목록 이해 :

[[float(y) for y in x] for x in l]

와 동일;

new_list=[]
for x in l:
    sub_list=[]
    for y in x:
        sub_list.append(float(y))

    new_list.append(sub_list)

print(new_list)

산출:

[[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]


답변

중첩 된 목록 이해가 마음에 들지 않으면 지도 기능도 사용할 수 있습니다.

>>> from pprint import pprint

>>> l = l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

>>> pprint(l)
[['40', '20', '10', '30'],
['20', '20', '20', '20', '20', '30', '20'],
['30', '20', '30', '50', '10', '30', '20', '20', '20'],
['100', '100'],
['100', '100', '100', '100', '100'],
['100', '100', '100', '100']]

>>> float_l = [map(float, nested_list) for nested_list in l]

>>> pprint(float_l)
[[40.0, 20.0, 10.0, 30.0],
[20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0],
[30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0],
[100.0, 100.0],
[100.0, 100.0, 100.0, 100.0, 100.0],
[100.0, 100.0, 100.0, 100.0]]


답변

비슷한 문제가 있어서이 질문을 보았습니다. Andrew Clark와 narayan의 답변을 공유하고 싶은 성능을 비교했습니다.

두 답변의 주요 차이점은 내부 목록을 반복하는 방법입니다. 그중 하나는 내장 map을 사용 하고 다른 하나는 목록 이해를 사용합니다. 람다 사용이 필요하지 않은 경우 Map 함수는 동등한 목록 이해에 비해 약간의 성능 이점이 있습니다 . 따라서이 질문의 맥락에서map 목록 이해력보다 약간 더 나은 성능을 발휘해야합니다.

성능 벤치 마크를 통해 실제로 적용되는지 확인할 수 있습니다. 파이썬 버전 3.5.0을 사용하여 이러한 모든 테스트를 수행했습니다. 첫 번째 테스트 세트에서 목록 당 요소를 10 으로 유지 하고 목록 수를 10-100,000으로 변경하고 싶습니다.

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10]"
>>> 10000 loops, best of 3: 19.6 usec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100]"
>>> 10000 loops, best of 3: 19.6 usec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*1000]"
>>> 1000 loops, best of 3: 1.43 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*1000]"
>>> 100 loops, best of 3: 1.91 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10000]"
>>> 100 loops, best of 3: 13.6 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10000]"
>>> 10 loops, best of 3: 19.1 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 164 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 216 msec per loop

여기에 이미지 설명을 입력하십시오

다음 테스트 세트에서 목록 당 요소 수를 100 으로 늘리고 싶습니다 .

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 110 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 151 usec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.11 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.5 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 11.2 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 16.7 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 134 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 171 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.32 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.7 sec per loop

여기에 이미지 설명을 입력하십시오

용감한 발걸음을 내딛고 목록의 요소 수를 1000으로 수정합니다.

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 800 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 1.16 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 8.26 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 11.7 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 83.8 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 118 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 868 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 1.23 sec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 9.2 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 12.7 sec per loop

여기에 이미지 설명을 입력하십시오

이 테스트 map에서이 경우 목록 이해에 비해 성능 이점이 있다고 결론을 내릴 수 있습니다 . int또는 로 캐스트하려는 경우에도 적용됩니다 str. 목록 당 요소 수가 적은 적은 수의 목록의 경우 그 차이는 무시할 수 있습니다. 목록 당 더 많은 요소가있는 더 큰 목록 map의 경우 목록 이해 대신 사용하고 싶을 수도 있지만 이는 응용 프로그램 요구에 따라 달라집니다.

그러나 개인적으로 나는 목록 이해가보다 읽기 쉽고 관용적이라고 생각 map합니다. 파이썬에서 사실상의 표준입니다. 일반적으로 사람들은 목록 이해력보다보다 능숙하고 편안합니다 (특히 초보자) map.