이를 지원하는 언어로 여러 값을 반환하는 표준 방법은 종종튜플 링.
이 간단한 예제를 생각해보십시오.
def f(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return (y0,y1,y2)
그러나 반환 된 값의 수가 증가하면 문제가 신속하게 해결됩니다. 4 개 또는 5 개의 값을 반환하려면 어떻게해야합니까? 물론, 당신은 그들을 묶어 둘 수 있지만, 어떤 가치가 있는지를 잊기 쉽습니다. 당신이 그들을 받고 싶을 때마다 그것들을 푸는 것이 오히려 추한 것입니다.
다음 논리적 인 단계는 일종의 '레코드 표기법'을 소개하는 것 같습니다. 파이썬에서는 이것을하기위한 확실한 방법은dict
.
다음을 고려하세요:
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0':y0, 'y1':y1 ,'y2':y2 }
(편집 - 그냥 분명히, y0, y1 및 y2 추상 식별자 의미입니다. 실제로 지적한 의미있는 식별자를 사용하여 지적한대로)
이제 우리는 반환 된 객체의 특정 멤버를 프로젝션 할 수있는 메커니즘을 가지고 있습니다. 예를 들어,
result['y0']
그러나 다른 옵션이 있습니다. 대신 특수 구조를 반환 할 수 있습니다. 나는 이것을 파이썬의 맥락에서 설명했다. 그러나 다른 언어에도 적용 할 수있을 것이라고 확신한다. 실제로, C에서 일하고 있다면 이것이 유일한 옵션 일 것입니다. 여기에 간다 :
class ReturnValue(object):
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
파이썬에서는 앞의 두 가지가 아마도 배관과 관련하여 매우 유사 할 것입니다.{ y0, y1, y2 }
내부적으로 엔트리가 끝난다.__dict__
~의ReturnValue
.
Python에서 제공하는 추가 기능 중 하나가 작은 객체 인 경우__slots__
속성. 클래스는 다음과 같이 표현 될 수 있습니다.
class ReturnValue(object):
__slots__ = ["y0", "y1", "y2"]
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
그만큼
__slots__
선언은 일련의 인스턴스 변수를 취하고 각 인스턴스에 각 변수에 대한 값을 보유하기에 충분한 공간을 예약합니다. 공간이 절약됩니다. 왜냐하면__dict__
각 인스턴스에 대해 만들어지지 않습니다.
내가 간과 한 또 다른 제안은 도마뱀 빌 (Bill the Lizard)
def h(x):
result = [x + 1]
result.append(x * 3)
result.append(y0 ** y3)
return result
그래도 내가 가장 좋아하지 않는 방법입니다. 나는 하스켈에 노출되면서 오염 된 것 같지만, 혼합 타입리스트에 대한 생각은 항상 나에게 불편 함을 느꼈다. 이 특별한 예에서리스트는 -not- 혼합 유형이지만 생각할 수 있습니다. 이 방법으로 사용 된리스트는 내가 말할 수있는 한 튜플에 관해서는 아무 것도 얻지 못합니다. 파이썬에서리스트와 튜플의 유일한 차이점은리스트가변하기 쉬운, 튜플은 없습니다. 개인적으로 함수형 프로그래밍의 관례를 따르는 경향이 있습니다. 같은 유형의 요소를 여러 개 사용하고 미리 정해진 유형의 요소를 고정 된 수만큼 튜플을 사용합니다.
오랜 전공 끝에 피할 수없는 질문이옵니다. 어떤 방법 (생각하십니까?)이 가장 좋습니다.
일반적으로 사전 설정 작업이 적기 때문에 사전 경로를 사용하고 있습니다. 그러나 유형 관점에서, 당신은 사전을 나타내는 것이 혼란스럽게되는 것을 피할 수 있기 때문에 클래스 경로를 벗어나는 것이 더 나을 것입니다. 반면에, 파이썬 공동체에는 느낄 수있는 것들이 있습니다.묵시적 인터페이스가 명시 적 인터페이스보다 우선되어야한다.이 시점에서 객체의 유형은 실제로는 관련이 없습니다. 기본적으로 같은 속성이 항상 동일한 의미를 가지게된다는 관습에 의존하기 때문입니다.
그렇다면 파이썬에서 다중 값을 반환하는 방법은 무엇입니까?
명명 된 튜플이 목적으로 2.6에 추가되었습니다. 참조os.stat유사한 기본 제공 예제입니다.
>>> import collections
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(1, y=2)
>>> p.x, p.y
1 2
>>> p[0], p[1]
1 2
최근 버전의 Python 3 (3.6 이상, 내가 생각하기에), 새로운typing
도서관에NamedTuple
클래스를 사용하여 명명 된 튜플을보다 쉽게 만들고 더 강력하게 만듭니다. 상속자typing.NamedTuple
문서 문자열, 기본값 및 유형 주석을 사용할 수 있습니다.
예제 (문서에서) :
class Employee(NamedTuple): # inherit from collections.NamedTuple
name: str
id: int = 3 # default value
employee = Employee('Guido')
assert employee.id == 3
namedtuple
에 대한 작은 메모리 풋 프린트가 있습니다.질량결과 (DB 쿼리의 결과와 같은 튜플의 긴 목록). 개별 항목의 경우 (문제의 기능이 자주 호출되지 않는 경우) 사전과 수업은 잘됩니다. 그러나 namedtuples은이 경우에도 좋고 / 더 나은 솔루션입니다. - Lutz Precheltp=collections.namedtuple('point','x,y')(1,2)
- Dave Xnamedtuple
정의 (각 호출은 새로운 호출을 생성 함),namedtuple
클래스는 CPU와 메모리 모두에서 상대적으로 비용이 많이 들며 모든 클래스 정의는 본질적으로 순환 참조를 포함합니다 (CPython에서 주기적 GC 실행이 릴리스되기를 기다리고 있습니다). 그것은 또한 불가능하게 만든다.pickle
클래스 (따라서 인스턴스를multiprocessing
대부분의 경우에). 내 3.6.4 x64에서 클래스를 만들 때마다 ~ 0.337ms가 소모되고 메모리가 1KB 미만으로 줄어들어 인스턴스 절감 효과가 사라집니다. - ShadowRanger
소규모 프로젝트의 경우 튜플을 사용하여 작업하는 것이 가장 쉽습니다. 그렇게되면 관리하기가 너무 어려워지고 전에는 논리적 구조로 그룹 짓기 시작합니다. 그러나 사전과 ReturnValue 객체의 사용은 잘못된 것입니다 (또는 너무 단순합니다).
y0, y1, y2 등의 키를 가진 사전을 반환하는 것은 튜플보다 이점을 제공하지 않습니다. .y0 .y1 .y2 등의 속성을 가진 ReturnValue 인스턴스를 반환해도 튜플보다 유리하지는 않습니다. 어쨌든 튜플 (tuples)을 사용하면 어디든 갈 수 있습니다.
def getImageData(filename):
[snip]
return size, (format, version, compression), (width,height)
size, type, dimensions = getImageData(x)
IMHO, 터플을 뛰어 넘는 유일한 좋은 기술은 적절한 메소드와 속성을 가진 실제 객체를 반환하는 것입니다.re.match()
또는open(file)
.
size, type, dimensions = getImageData(x)
과(size, type, dimensions) = getImageData(x)
? 즉, 배제 된 과제의 왼손 쪽을 감싸는 것이 어떤 차이를 만들어 낼 수 있습니까? - Reb.Cabin(1)
int 인 동안(1,)
또는1,
튜플입니다. - phil
많은 답변은 사전이나 목록과 같은 일종의 컬렉션을 반환해야한다고 제안합니다. 추가 구문을 생략하고 쉼표로 구분 된 반환 값을 쓸 수 있습니다. 참고 : 이것은 기술적으로 튜플을 반환합니다.
def f():
return True, False
x, y = f()
print(x)
print(y)
제공 :
True
False
type(f())
보고<class 'tuple'>
. - Igortuple
aspect 명시 적; 다시 돌아 오는 것이 중요하지 않습니다.tuple
이것은 여러 값을 반환하는 관용구입니다. 스왑 이디엄으로 괄호를 생략하는 것과 같은 이유가 있습니다.x, y = y, x
, 다중 초기화x, y = 0, 1
등; 물론,tuple
후드 아래에 있지만, 명시 적으로 만들 이유가 없습니다.tuple
전혀 요점은 아닙니다. 파이썬 튜토리얼다중 과제를 소개하다심지어 만지기 훨씬 전에tuple
에스. - ShadowRanger
나는 사전에 투표한다.
나는 2-3 개 이상의 변수를 반환하는 함수를 만들면 사전에 그 변수를 접을 것입니다. 그렇지 않으면 내가 돌아 오는 것의 순서와 내용을 잊어 버리는 경향이 있습니다.
또한 '특수'구조를 도입하면 코드를 따르기가 더 어려워집니다. (다른 사람이 무엇인지 알아 내기 위해 코드를 검색해야합니다.)
유형 조회에 관심이 있다면 'x-values list'와 같은 설명적인 사전 키를 사용하십시오.
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0':y0, 'y1':y1 ,'y2':y2 }
result = g(x); other_function(result)
- monkut
또 다른 옵션은 발전기를 사용하는 것입니다.
>>> def f(x):
y0 = x + 1
yield y0
yield x * 3
yield y0 ** 4
>>> a, b, c = f(5)
>>> a
6
>>> b
15
>>> c
1296
반환되는 값이 클래스에서의 캡슐화의 후보가되는 경우를 제외하고는 일반적으로 IMHO 튜플이 가장 좋습니다.
yield
? - CoreDumpError
튜플이 "자연스러운"느낌이들 때마다 튜플을 사용하는 것을 선호합니다. 좌표는 일반적인 예이며, 별도의 객체가 자체적으로 서있을 수 있습니다. 1 축 스케일링 계산만으로, 순서가 중요합니다. 참고 : 그룹의 의미에 악영향을 미치지 않고 항목을 정렬하거나 섞을 수 있다면 튜플을 사용하지 않아야합니다.
그룹화 된 객체가 항상 동일하지 않은 경우에만 사전을 반환 값으로 사용합니다. 선택적 이메일 헤더를 생각해보십시오.
나머지 그룹의 경우, 그룹화 된 오브젝트가 그룹 내에서 고유 한 의미를 가지거나 자체 메소드가있는 완전한 오브젝트가 필요한 경우, 클래스를 사용합니다.
나는 선호한다
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0':y0, 'y1':y1 ,'y2':y2 }
다른 모든 것들이 똑같은 일을하기위한 여분의 코드 일 뿐이라고 생각합니다.
>>> def func():
... return [1,2,3]
...
>>> a,b,c = func()
>>> a
1
>>> b
2
>>> c
3
파이썬의 튜플 (tuple), 딕트 (dicts), 객체 (object)는 프로그래머가 소규모 데이터 구조 ( "사물")에 대한 형식과 편의성을 원활하게 교환 할 수있게합니다. 나에게있어서, 어떤 것을 표현하는 방법의 선택은 주로 어떻게 구조를 사용할 것인지에 달려있다. C ++에서 사용하는 일반적인 규칙struct
데이터 전용 항목 및class
메소드를 가진 객체의 경우, 메소드를 합법적으로struct
; 내 습관은 파이썬에서 비슷하다.dict
과tuple
대신에struct
.
좌표 세트의 경우,tuple
한 점보다class
또는dict
(그리고 당신이 사용할 수있는tuple
사전 키로dict
훌륭한 스파 스 다차원 배열을 만든다.
내가 물건의 목록을 반복 할 예정이라면, 나는 풀기를 선호한다.tuple
반복에 :
for score,id,name in scoreAllTheThings():
if score > goodScoreThreshold:
print "%6.3f #%6d %s"%(score,id,name)
... 객체 버전이 읽기에 더 어수선하기 때문에 :
for entry in scoreAllTheThings():
if entry.score > goodScoreThreshold:
print "%6.3f #%6d %s"%(entry.score,entry.id,entry.name)
... 혼자 내버려 둬.dict
.
for entry in scoreAllTheThings():
if entry['score'] > goodScoreThreshold:
print "%6.3f #%6d %s"%(entry['score'],entry['id'],entry['name'])
그 일이 널리 쓰이고 있으며 코드의 여러 위치에서 이와 유사한 간단한 조작을하는 경우에는 적절한 방법으로 클래스 객체로 만드는 것이 좋습니다.
마지막으로, 파이썬이 아닌 시스템 구성 요소와 데이터를 교환하려고한다면, 나는 종종 그것들을dict
이는 JSON 직렬화에 가장 적합하기 때문입니다.
일반적으로 "특수 구조"는 실제로 객체의 현명한 현재 상태이며 고유 한 방법을 사용합니다.
class Some3SpaceThing(object):
def __init__(self,x):
self.g(x)
def g(self,x):
self.y0 = x + 1
self.y1 = x * 3
self.y2 = y0 ** y3
r = Some3SpaceThing( x )
r.y0
r.y1
r.y2
나는 가능한 한 익명의 구조체의 이름을 찾고 싶다. 의미있는 이름은 일을 더 분명하게 만듭니다.
S.Lott의 명명 된 컨테이너 클래스 제안에 +1.
파이썬 2.6 이상에서는명명 된 튜플이러한 컨테이너 클래스를 쉽게 만들 수있는 유용한 방법을 제공하며 결과는 "가볍고 일반 튜플보다 더 많은 메모리가 필요하지 않습니다."
파이썬과 같은 언어에서는 일반적으로 새 클래스를 만드는 것보다 오버 헤드가 적기 때문에 사전을 사용합니다.
그러나, 자신이 끊임없이 동일한 변수 세트를 반환한다면, 아마도 그것은 배제 할 새로운 클래스를 포함 할 것입니다.
함수에서 값을 전달하고 반환하는 데 dict을 사용합니다.
정의 된대로 변수 형식 사용형태.
form = {
'level': 0,
'points': 0,
'game': {
'name': ''
}
}
def test(form):
form['game']['name'] = 'My game!'
form['level'] = 2
return form
>>> print(test(form))
{u'game': {u'name': u'My game!'}, u'points': 0, u'level': 2}
이것은 나를 위해 그리고 처리 장치를위한 가장 효율적인 방법입니다.
하나의 포인터를 전달하고 하나의 포인터 만 리턴해야합니다.
코드를 변경할 때마다 함수의 수천 개의 인수를 변경할 필요가 없습니다.
"최고"는 부분적으로 주관적인 결정입니다. 변경할 수없는 일반적인 경우에는 작은 리턴 세트에 튜플을 사용하십시오. 튜플은 변경 가능성이 요구 사항이 아닌 경우 목록보다 항상 바람직합니다.
더 복잡한 반환 값 또는 형식이 중요한 경우 (즉, 값이 큰 코드) 이름이 지정된 튜플이 더 좋습니다. 가장 복잡한 경우에는 일반적으로 객체가 가장 좋습니다. 그러나 실제로 중요한 상황입니다. 그것이 함수의 끝에서 자연스럽게 가지고있는 것이기 때문에 (예 : 팩토리 패턴) 객체를 반환하는 것이 합리적이라면 객체를 반환하십시오.
현자가 말한대로 :
조숙 한 최적화는 모든 악의 뿌리이다. 그것) 프로그래밍.
y3
, 그러나 y3가 전역으로 선언되지 않으면, 이것은 yNameError: global name 'y3' is not defined
아마도 그냥 사용3
? - hetepeperfan