[python] 리스트 이해의 이중 반복

파이썬에서는 목록 이해에 여러 반복자를 가질 수 있습니다.

[(x,y) for x in a for y in b]

일부 적합한 서열 a 및 b. 파이썬의 목록 이해의 중첩 루프 의미를 알고 있습니다.

내 질문은 : 이해의 한 반복자가 다른 반복자를 참조 할 수 있습니까? 다른 말로하면 다음과 같습니다.

[x for x in a for a in b]

외부 루프의 현재 값은 내부의 반복자입니까?

예를 들어 중첩 목록이있는 경우 :

a=[[1,2],[3,4]]

이 결과를 달성하기 위해 목록 이해 표현은 무엇입니까?

[1,2,3,4]

?? (이것이 내가 알고 싶은 것이기 때문에 이해력 답변 만 나열하십시오).



답변

자신의 제안으로 질문에 대답하려면 :

>>> [x for b in a for x in b] # Works fine

목록 이해 답변을 요청하는 동안 훌륭한 itertools.chain ()도 지적하겠습니다.

>>> from itertools import chain
>>> list(chain.from_iterable(a))
>>> list(chain(*a)) # If you're using python < 2.6


답변

a,b,x,y에게 큰 의미가 없기 때문에 이것이 다른 누군가를 돕기를 바랍니다 . 문장으로 가득 찬 텍스트가 있고 단어 배열을 원한다고 가정하십시오.

# Without list comprehension
list_of_words = []
for sentence in text:
    for word in sentence:
       list_of_words.append(word)
return list_of_words

나는 목록 이해력을 수평으로 늘리는 것으로 생각하고 싶다.

그것을 다음과 같이 나누십시오.

# List Comprehension 
[word for sentence in text for word in sentence]

예:

>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> [word for sentence in text for word in sentence]
['Hi', 'Steve!', "What's", 'up?']

이것은 발전기에서도 작동합니다.

>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> gen = (word for sentence in text for word in sentence)
>>> for word in gen: print(word)
Hi
Steve!
What's
up?


답변

Gee, 나는 anwser를 발견했다고 생각한다. 나는 어떤 루프가 내부이고 어떤 루프가 외부인지에 대해 충분히 신경 쓰지 않고 있었다. 목록 이해력은 다음과 같아야합니다.

[x for b in a for x in b]

원하는 결과를 얻으려면 예, 현재 값 중 하나는 다음 루프의 반복자가 될 수 있습니다.


답변

반복자의 순서는 직관적이지 않을 수 있습니다.

예를 들어 보자. [str(x) for i in range(3) for x in foo(i)]

그것을 분해하자 :

def foo(i):
    return i, i + 0.5

[str(x)
    for i in range(3)
        for x in foo(i)
]

# is same as
for i in range(3):
    for x in foo(i):
        yield str(x)


답변

ThomasH는 이미 좋은 답변을 추가했지만 어떻게되는지 보여주고 싶습니다.

>>> a = [[1, 2], [3, 4]]
>>> [x for x in b for b in a]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined

>>> [x for b in a for x in b]
[1, 2, 3, 4]
>>> [x for x in b for b in a]
[3, 3, 4, 4]

파이썬이 목록 이해를 왼쪽에서 오른쪽으로 구문 분석한다고 생각합니다. 즉, for발생 하는 첫 번째 루프가 먼저 실행됩니다.

이것의 두 번째 “문제” b는 목록 이해에서 “누설” 된다는 것입니다. 첫 번째 성공적인 목록 이해 후 b == [3, 4].


답변

다차원 배열을 유지하려면 배열 괄호를 중첩해야합니다. 모든 요소에 하나가 추가되는 아래 예를 참조하십시오.

>>> a = [[1, 2], [3, 4]]

>>> [[col +1 for col in row] for row in a]
[[2, 3], [4, 5]]

>>> [col +1 for row in a for col in row]
[2, 3, 4, 5]


답변

이 메모리 기술은 많은 도움이됩니다.

[ <RETURNED_VALUE> <OUTER_LOOP1> <INNER_LOOP2> <INNER_LOOP3> ... <OPTIONAL_IF> ]

그리고 지금 당신에 대해 생각할 수있는 R eturn + O 유일한로 터의 루프 R ight O RDER

위에서 알 수 있듯이 3 루프에서도 포괄적 인 목록의 순서는 쉽습니다.


c=[111, 222, 333]
b=[11, 22, 33]
a=[1, 2, 3]

print(
  [
    (i, j, k)                            # <RETURNED_VALUE> 
    for i in a for j in b for k in c     # in order: loop1, loop2, loop3
    if i < 2 and j < 20 and k < 200      # <OPTIONAL_IF>
  ]
)
[(1, 11, 111)]

위의 내용은 다음과 같습니다.

for i in a:                         # outer loop1 GOES SECOND
  for j in b:                       # inner loop2 GOES THIRD
    for k in c:                     # inner loop3 GOES FOURTH
      if i < 2 and j < 20 and k < 200:
        print((i, j, k))            # returned value GOES FIRST

하나의 중첩 된 목록 / 구조를 반복하는 경우 기술은 동일 a합니다.

a = [[1,2],[3,4]]
[i2    for i1 in a      for i2 in i1]
which return [1, 2, 3, 4]

서로 중첩 된 레벨

a = [[[1, 2], [3, 4]], [[5, 6], [7, 8, 9]], [[10]]]
[i3    for i1 in a      for i2 in i1     for i3 in i2]
which return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

등등