[PYTHON] 고급 중첩 목록 이해 구문
PYTHON고급 중첩 목록 이해 구문
나는 그들에 대한 더 나은 이해를 얻기 위해리스트 comprehensions로 놀고 있었고, 나는 설명 할 수없는 예상치 못한 결과물을 만났다. 전에 질문 한이 질문을 찾지 못했지만, 그것이 반복되는 질문이라면 사과드립니다.
저는 본질적으로 발전기를 생성하는 발전기를 작성하려고했습니다. 목록 이해력을 사용하는 간단한 생성기는 다음과 같습니다.
(x for x in range(10) if x%2==0) # generates all even integers in range(10)
내가 뭘 하려던 것은 두 개의 생성기를 생성하는 생성기를 작성하는 것입니다. 처음에는 범위 (10)의 짝수를 생성하고 두 번째 생성자는 범위 (10)의 홀수를 생성했습니다. 이것을 위해, 나는했다 :
>>> (x for x in range(10) if x%2==i for i in range(2))
<generator object <genexpr> at 0x7f6b90948f00>
>>> for i in g.next(): print i
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
UnboundLocalError: local variable 'i' referenced before assignment
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> g = (x for x in range(10) if x%2==i for i in range(2))
>>> g
<generator object <genexpr> at 0x7f6b90969730>
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
UnboundLocalError: local variable 'i' referenced before assignment
나는 왜 '나'가 과제 전에 참조되고 있는지 이해하지 못한다.
나는 그것이 범위 (2)에서 내가해야 할 일이있을 것이라고 생각했기 때문에 나는 그렇게했다 :
>>> g = (x for x in range(10) if x%2==i for i in [0.1])
>>> g
<generator object <genexpr> at 0x7f6b90948f00>
>>> g.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
UnboundLocalError: local variable 'i' referenced before assignment
이것은 나에게 의미가 없었기 때문에, 먼저 더 간단한 것을 시도하는 것이 가장 좋다고 생각했습니다. 그래서 나는 목록으로 돌아가서 다음을 시도했다.
>>> [x for x in range(10) if x%2==i for i in range(2)]
[1, 1, 3, 3, 5, 5, 7, 7, 9, 9]
나는 다음과 같은 것으로 기대했다.
>>> l = []
>>> for i in range(2):
... for x in range(10):
... if x%2==i:
... l.append(x)
...
>>> l
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9] # so where is my list comprehension malformed?
그러나 나는 그것을 직감으로 시험해 보았을 때 다음과 같이 작동했습니다.
>>> [[x for x in range(10) if x%2==i] for i in range(2)]
[[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]] # so nested lists in nested list comprehension somehow affect the scope of if statements? :S
그래서 if 문이 어느 수준의 범위에서 작동하는지 문제가 될 수 있다고 생각했습니다. 그래서 이것을 시도했습니다 :
>>> [x for x in range(10) for i in range(2) if x%2==i]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
그리고 지금 나는 완전히 혼란 스럽다. 누군가이 행동을 설명해 주시겠습니까? 내 목록 내포가 잘못된 형식으로 보이는 이유를 이해하지 못하거나 if 문 범위가 작동하는 방식을 이해하지 못합니다.
추신 : 질문을 증명하는 동안, 나는 이것이 숙제 문제처럼 보임을 깨달았습니다. 그렇지 않습니다.
해결법
-
==============================
1.괄호를 사용해야합니다.
괄호를 사용해야합니다.
((x for x in range(10) if x%2==i) for i in range(2))
이전 목록의 이해력이 i 변수를 둘러싼 범위로 누설하고 현재 범위의 i가 되었기 때문에 효과가있었습니다. 새로운 파이썬 인터프리터를 시작하면 NameError로 인해 실패합니다. 카운터의 누수 동작은 Python 3에서 제거되었습니다.
편집하다:
다음과 같은 for 루프 :
(x for x in range(10) if x%2==i for i in range(2))
다음과 같습니다 :
l = [] for x in range(10): if x%2 == i: for i in range(2): l.append(x)
또한 이름 오류를 제공합니다.
EDIT2 :
괄호 안의 버전 :
((x for x in range(10) if x%2==i) for i in range(2))
다음과 같습니다.
li = [] for i in range(2): lx = [] for x in range(10): if x%2==i: lx.append(x) li.append(lx)
-
==============================
2.Ryan Ryan의 for-loop에 해당하는 것은 다음과 같은 결과를 낳았습니다.
Ryan Ryan의 for-loop에 해당하는 것은 다음과 같은 결과를 낳았습니다.
[x for i in range(2) for x in range(10) if i == x%2]
산출물
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
-
==============================
3.Lie Ryan의 대답을 약간 확장하면 다음과 같습니다.
Lie Ryan의 대답을 약간 확장하면 다음과 같습니다.
뭔가 = (범위 (2)에있는 x % 2 == i 인 경우 범위 (10)의 x에 대한 x)
다음과 같습니다.
def _gen1(): for x in range(10): if x%2 == i: for i in range(2): yield x something = _gen1()
괄호로 묶인 버전은 다음과 같습니다.
def _gen1(): def _gen2(): for x in range(10): if x%2 == i: yield x for i in range(2): yield _gen2() something = _gen1()
이것은 실제로 두 개의 생성기를 생성합니다.
[<generator object <genexpr> at 0x02A0A968>, <generator object <genexpr> at 0x02A0A990>]
불행히도 출력은 생성 방법에 따라 출력이 다소 불안정합니다.
>>> gens = ((x for x in range(10) if x%2==i) for i in range(2)) >>> for g in gens: print(list(g)) [0, 2, 4, 6, 8] [1, 3, 5, 7, 9] >>> gens = ((x for x in range(10) if x%2==i) for i in range(2)) >>> for g in list(gens): print(list(g)) [1, 3, 5, 7, 9] [1, 3, 5, 7, 9]
내 충고는 생성기 함수를 전부 작성하는 것입니다. 그 일을하지 않고 올바른 범위 지정을 시도하는 것이 불가능할 수도 있습니다.
-
==============================
4.거짓말은 구문 론적 질문에 답을줍니다. 제안 : 발전기의 몸에 많은 것을 넣지 마십시오. 함수가 훨씬 더 읽기 쉽습니다.
거짓말은 구문 론적 질문에 답을줍니다. 제안 : 발전기의 몸에 많은 것을 넣지 마십시오. 함수가 훨씬 더 읽기 쉽습니다.
def make_generator(modulus): return (x for x in range(10) if x % 2 == modulus) g = (make_generator(i) for i in range(2))
from https://stackoverflow.com/questions/3766711/advanced-nested-list-comprehension-syntax by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] __str__ 및 __repr__의 목적은 무엇입니까? (0) | 2018.10.04 |
---|---|
[PYTHON] 파이썬에서 개인 및 보호 된 메소드의 상속 (0) | 2018.10.04 |
[PYTHON] 내장 모듈과 이름이 같은 모듈을 가져 오려고하면 가져 오기 오류가 발생합니다. (0) | 2018.10.04 |
[PYTHON] 대화 형 Matplotlib 수치 저장 (0) | 2018.10.04 |
[PYTHON] 다중 상속을 가진 부모 클래스 __init__을 호출하는 것이 옳은 방법일까요? (0) | 2018.10.04 |