3.x를 사용하여 람다 매개 변수에 대한 2.x의 튜플 언팩을 시뮬레이션하려면 어떻게 해야 합니까?
파이썬 2에서 나는 다음을 쓸 수 있습니다.
In [5]: points = [ (1,2), (2,3)]
In [6]: min(points, key=lambda (x, y): (x*x + y*y))
Out[6]: (1, 2)
그러나 이는 3.x에서 지원되지 않습니다.
File "<stdin>", line 1
min(points, key=lambda (x, y): (x*x + y*y))
^
SyntaxError: invalid syntax
간단한 해결 방법은 전달된 튜플에 명시적으로 인덱싱하는 것입니다.
>>> min(points, key=lambda p: p[0]*p[0] + p[1]*p[1])
(1, 2)
이것은 매우 추합니다.람다가 함수라면, 나는 할 수 있습니다.
def some_name_to_think_of(p):
x, y = p
return x*x + y*y
하지만 그 이유는lambda
하며, 표만지며원하다, 넣을 수 .x, y = p
그 일에 끼어들다
이 제한을 어떻게 해결할 수 있습니까?
아니요, 다른 방법이 없어요.당신이 다 커버했어요.방법은 파이썬 아이디어 메일링 목록에 이 문제를 제기하는 것이지만, 관심을 끌기 위해 거기서 많은 논쟁을 벌일 준비가 되어 있습니다.
사실, "출구가 없다"는 말을 하지 않기 위해 세 번째 방법은 매개 변수를 펼치기 위해 람다 호출을 한 단계 더 구현하는 것일 수 있지만, 이는 두 가지 제안보다 동시에 더 비효율적이고 읽기 어려울 것입니다.
min(points, key=lambda p: (lambda x,y: (x*x + y*y))(*p))
Python 3.8 업데이트
Python 3.8 릴리스 이후 PEP 572(할당 표현식)를 도구로 사용할 수 있게 되었습니다.
따라서 람다 안에서 여러 식을 실행하기 위해 트릭을 사용하는 경우 - 저는 보통 튜플을 만들고 마지막 구성 요소만 반환하면 다음을 수행할 수 있습니다.
>>> a = lambda p:(x:=p[0], y:=p[1], x ** 2 + y ** 2)[-1]
>>> a((3,4))
25
이러한 종류의 코드는 완전한 기능을 갖는 것보다 더 읽기 쉽거나 실용적인 경우가 거의 없다는 것을 명심해야 합니다.여전히 사용 가능한 용도가 있습니다. 이에 대해 작동하는 다양한 한 줄기가 있는 경우point
그것은 가치가 있을 수 있습니다.namedtuple
할당 식을 사용하여 수신 시퀀스를 명명된 튜플에 효과적으로 "캐스트"합니다.
>>> from collections import namedtuple
>>> point = namedtuple("point", "x y")
>>> b = lambda s: (p:=point(*s), p.x ** 2 + p.y ** 2)[-1]
http://www.python.org/dev/peps/pep-3113/ 에 따르면 튜플 압축 풀기가 사라졌습니다.2to3
다음과 같이 번역합니다.
단일 식 제한 때문에 람다에서 튜플 매개 변수를 사용하므로 이 매개 변수도 지원해야 합니다.이 작업은 예상 시퀀스 인수를 단일 매개 변수에 바인딩한 다음 해당 매개 변수에 인덱싱함으로써 수행됩니다.
lambda (x, y): x + y
다음으로 변환됩니다.
lambda x_y: x_y[0] + x_y[1]
이는 귀사의 구현과 상당히 유사합니다.
저는 Python 2 인수 언팩 동작에 대한 좋은 일반적인 대안을 모릅니다.다음은 경우에 따라 유용할 수 있는 몇 가지 제안 사항입니다.
이름이 생각나지 않는 경우 키워드 매개 변수의 이름을 사용합니다.
def key(p): # more specific name would be better x, y = p return x**2 + y**3 result = min(points, key=key)
당신은 볼 수 있습니다.
namedtuple
목록이 여러 위치에서 사용되는 경우 코드를 보다 쉽게 읽을 수 있습니다.from collections import namedtuple from itertools import starmap points = [ (1,2), (2,3)] Point = namedtuple('Point', 'x y') points = list(starmap(Point, points)) result = min(points, key=lambda p: p.x**2 + p.y**3)
Python3에서 destructuring 인수가 제거되었지만, 이해에서 제거되지 않았습니다.이를 악용하여 Python 3에서 유사한 동작을 얻을 수 있습니다.
예:
points = [(1,2), (2,3)]
print(min(points, key=lambda y: next(x*x + y*y for (x,y) in [y])))
래퍼를 사용하는 것에 대한 허용된 답변과 비교하여, 이 솔루션은 래퍼가 첫 번째 레벨만 파괴하는 동안 인수를 완전히 구조화할 수 있습니다.즉, 할 수 있습니다.
values = [(('A',1),'a'), (('B',0),'b')]
print(min(values, key=lambda y: next(b for ((a,b),c) in (y,))))
래퍼 해제 람다를 사용하여 허용된 답변과 비교:
values = [(('A',1),'a'), (('B',0),'b')]
print(min(points, key=lambda p: (lambda a,b: (lambda x,y: (y))(*a))(*p)))
또는 튜플 대신 목록을 사용할 수도 있습니다.
values = [(('A',1),'a'), (('B',0),'b')]
print(min(points, key=lambda y: next(b for (a,b),c in [y])))
이는 수행할 수 있으며 권장 사항으로 간주해서는 안 된다는 것을 제안하기 위한 것입니다.하지만 IMO, 이것은 튜플에 여러 개의 표현을 사용하고 마지막 표현을 반환하는 해킹보다 낫습니다.
좋은 은 제생에더나것같다습니은각▁is라고 합니다.x * x + y * y let x, y = point
,let
키워드를 더 신중하게 선택해야 합니다.
이중 람다가 가장 가까운 버전입니다. lambda point: (lambda x, y: x * x + y * y)(*point)
고차 함수 도우미는 적절한 이름을 부여할 경우 유용할 것입니다.
def destruct_tuple(f):
return lambda args: f(*args)
destruct_tuple(lambda x, y: x * x + y * y)
태플의 압축을 풀 필요가 있는지 여부를 먼저 고려합니다.
min(points, key=lambda p: sum(x**2 for x in p))
또는 포장을 풀 때 명시적인 이름을 제공해야 하는지 여부:
min(points, key=lambda p: abs(complex(*p)**2)
이해관계에 풀기에 대한 의 의견을 은 Cuadue 안과압축대기의여초하견, 당용수있다니습다, 할사니제습있수할을 할 수 .numpy.argmin
:
result = points[numpy.argmin(x*x + y*y for x, y in points)]
또 다른 옵션은 키가 첫 번째 요소인 튜플을 생성하는 생성기에 입력하는 것입니다.튜플은 처음부터 끝까지 비교되므로 첫 번째 요소가 가장 작은 튜플이 반환됩니다.그런 다음 결과로 인덱싱하여 값을 가져올 수 있습니다.
min((x * x + y * y, (x, y)) for x, y in points)[1]
PyFunctional을 사용하면 이에 대한 진정한 해결책이 있을 수 있습니다!
현재 지원되지는 않지만 다음을 지원하기 위해 Tuplearg 압축 풀기 기능 요청을 제출했습니다.
(
seq((1, 2), (3, 4))
.map(unpack=lambda a, b: a + b)
) # => [3, 7]
스택 오버플로에 대한 질문은 질문에 답변을 포함하지 않아야 하며 명시적인 "업데이트" 섹션이 없어야 하므로 OP의 원래 "업데이트"를 적절한 답변으로 변환하여 커뮤니티 위키로 만들고 있습니다.
OP는 원래 이 솔루션이 "답안의 아이디어를 확장하는 것"이라고 주장했습니다.나는 그것이 어떤 대답을 의미하는지, 어떤 생각을 의미하는지 분간할 수 없습니다.이 아이디어는 앤서니와 기능적으로 동일합니다.hl의 대답, 하지만 그것은 몇 년 후에 나왔습니다.당시 답변 상태를 고려하면 OP의 오리지널 작품으로 손색이 없다고 생각합니다.)
다음과 같이 인수의 압축을 푸는 과정을 일반화하는 래퍼 함수를 만듭니다.
def star(f):
return lambda args: f(*args)
이제 우리는 이것을 사용하여 쓸 람다를 인수를 적절하게 수신할 수 있는 람다로 변환할 수 있습니다.
min(points, key=star(lambda x,y: (x*x + y*y))
우리는 funtool을 사용하여 이것을 더 정리할 수 있습니다.랩:
import functools
def star(f):
@functools.wraps(f)
def f_inner(args):
return f(*args)
return f_inner
언급URL : https://stackoverflow.com/questions/21892989/how-can-i-simulate-2-xs-tuple-unpacking-for-lambda-parameters-using-3-x
'programing' 카테고리의 다른 글
이클립스에서 동적 웹 프로젝트의 컨텍스트 루트를 변경하는 방법은 무엇입니까? (0) | 2023.05.05 |
---|---|
하위 디렉터리를 제외한 모든 것을 무시하도록 Git에게 어떻게 말합니까? (0) | 2023.05.05 |
git pull origin 마스터와 git pull origin/master 간의 차이 (0) | 2023.05.05 |
콘텐츠를 삭제하지 않고 많은 수의 파일을 분할하는 방법 (0) | 2023.05.05 |
바이트를 int로 변환하시겠습니까? (0) | 2023.05.05 |