programing

파이썬 람다 식에 여러 개의 문을 가질 수 있습니까?

newsource 2023. 7. 19. 21:23

파이썬 람다 식에 여러 개의 문을 가질 수 있습니까?

목록이 있습니다.

lst = [[567, 345, 234], [253, 465, 756, 2345], [333, 777, 111, 555]]

지도를 원합니다.lst각 하위 목록에서 두 번째로 작은 숫자만 포함된 다른 목록으로 이동합니다.그래서 결과는 다음과 같습니다.[345, 465, 333].

가 가장 , 저는 을 약만내가작숫관있다면나, 쓸수있다니습이을것으로 쓸 수 있을 입니다.map(lambda x: min(x), lst)두 번째로 작은 숫자를 얻기 위해, 저는 다음과 같은 결과를 정렬하고 색인화하는 것을 생각했습니다.map(lambda x: sort(x)[1], lst) 그나러,,sort 체인 대신 없음을 반환합니다.

여러 개의 문을 사용할 수 있는 경우lambda나는 쓸 수 있었습니다.map(lambda x: sort(x); x[1], lst)하지만 이것은 허용되지 않습니다.

사용할 수 있습니까?map지정된 함수를 정의하지 않고 문제를 해결하는 것? 어떻게?

여기서 제가 드릴 수 있는 답변은 구체적인 질문에서부터 일반적인 관심사에 이르기까지 몇 가지가 있습니다.그래서 가장 구체적인 것부터 가장 일반적인 것까지:

Q. 람다에 여러 문을 넣을 수 있습니까?

A. 아니요. 하지만 실제로 람다를 사용할 필요는 없습니다.문을 다음과 같이 입력할 수 있습니다.def대신. 즉:

def second_lowest(l):
    l.sort()
    return l[1]

map(second_lowest, lst)

Q. 목록을 정렬하여 람다에서 두 번째로 낮은 항목을 얻을 수 있습니까?

A. 네. 알렉스의 대답이 지적했듯이,sorted()내부 정렬 대신 새 목록을 만드는 정렬 버전으로, 연결할 수 있습니다.이것은 아마도 여러분이 사용해야 할 것입니다. 지도가 원래 목록에 부작용을 일으키는 것은 나쁜 관행입니다.

Q. 목록 순서에서 각 목록에서 두 번째로 낮은 항목을 얻으려면 어떻게 해야 합니까?

sorted(l)[1]이것을 위한 최선의 방법은 아닙니다.O(n) 솔루션이 존재하는 동안 O(N 로그(N) 복잡도가 있습니다.이 문제는 hipq 모듈에서 확인할 수 있습니다.

>>> import  heapq
>>> l = [5,2,6,8,3,5]
>>> heapq.nsmallest(l, 2)
[2, 3]

사용하기만 하면 됩니다.

map(lambda x: heapq.nsmallest(x,2)[1],  list_of_lists)

또한 일반적으로 람다를 완전히 피하는 목록 이해를 사용하는 것이 더 명확한 것으로 간주됩니다.

[heapq.nsmallest(x,2)[1] for x in list_of_lists]

식을 목록에 넣으면 여러 식을 시뮬레이션할 수 있습니다.

예:

lambda x: [f1(x), f2(x), f3(x), x+1]

문에는 사용할 수 없습니다.

여기 시간여행자.일반적으로 람다 내에 여러 문을 포함하려면 다른 람다를 해당 람다에 인수로 전달할 수 있습니다.

(lambda x, f: list((y[1] for y in f(x))))(lst, lambda x: (sorted(y) for y in x))

실제로 여러 개의 문장을 가질 수는 없지만, 람다를 람다로 전달함으로써 시뮬레이션할 수 있습니다.

편집: 여행자가 돌아오는 시간!또한 단락 규칙 및 진실성을 염두에 둔 부울식의 동작을 체인 작업에 악용할 수 있습니다.3진 연산자를 사용하면 훨씬 더 많은 힘을 얻을 수 있습니다.다시 말하지만, 여러 의 문을 가질 수는 없지만 물론 많은 함수 호출을 가질 수 있습니다.이 예제는 데이터 묶음으로 임의의 정크를 수행하지만, 재미있는 작업을 수행할 수 있음을 보여줍니다.인쇄 명령문은 반환되는 함수의 예입니다.None로됨).sort()방법) 하지만 그들은 또한 무엇을 보여주는 데 도움이 됩니다.lambda하고 있습니다.

>>> (lambda x: print(x) or x+1)(10)
10
11
>>> f = (lambda x: x[::2] if print(x) or x.sort() else print(enumerate(x[::-1]) if print(x) else filter(lambda (i, y): print((i, y)) or (i % 3 and y % 2), enumerate(x[::-1]))))
>>> from random import shuffle
>>> l = list(range(100))
>>> shuffle(l)
>>> f(l)
[84, 58, 7, 99, 17, 14, 60, 35, 12, 56, 26, 48, 55, 40, 28, 52, 31, 39, 43, 96, 64, 63, 54, 37, 79, 25, 46, 72, 10, 59, 24, 68, 23, 13, 34, 41, 94, 29, 62, 2, 50, 32, 11, 97, 98, 3, 70, 93, 1, 36, 87, 47, 20, 73, 45, 0, 65, 57, 6, 76, 16, 85, 95, 61, 4, 77, 21, 81, 82, 30, 53, 51, 42, 67, 74, 8, 15, 83, 5, 9, 78, 66, 44, 27, 19, 91, 90, 18, 49, 86, 22, 75, 71, 88, 92, 33, 89, 69, 80, 38]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
(0, 99)
(1, 98)
(2, 97)
(3, 96)
(4, 95)
(5, 94)
(6, 93)
(7, 92)
(8, 91)
(9, 90)
(10, 89)
(11, 88)
(12, 87)
(13, 86)
(14, 85)
(15, 84)
(16, 83)
(17, 82)
(18, 81)
(19, 80)
(20, 79)
(21, 78)
(22, 77)
(23, 76)
(24, 75)
(25, 74)
(26, 73)
(27, 72)
(28, 71)
(29, 70)
(30, 69)
(31, 68)
(32, 67)
(33, 66)
(34, 65)
(35, 64)
(36, 63)
(37, 62)
(38, 61)
(39, 60)
(40, 59)
(41, 58)
(42, 57)
(43, 56)
(44, 55)
(45, 54)
(46, 53)
(47, 52)
(48, 51)
(49, 50)
(50, 49)
(51, 48)
(52, 47)
(53, 46)
(54, 45)
(55, 44)
(56, 43)
(57, 42)
(58, 41)
(59, 40)
(60, 39)
(61, 38)
(62, 37)
(63, 36)
(64, 35)
(65, 34)
(66, 33)
(67, 32)
(68, 31)
(69, 30)
(70, 29)
(71, 28)
(72, 27)
(73, 26)
(74, 25)
(75, 24)
(76, 23)
(77, 22)
(78, 21)
(79, 20)
(80, 19)
(81, 18)
(82, 17)
(83, 16)
(84, 15)
(85, 14)
(86, 13)
(87, 12)
(88, 11)
(89, 10)
(90, 9)
(91, 8)
(92, 7)
(93, 6)
(94, 5)
(95, 4)
(96, 3)
(97, 2)
(98, 1)
(99, 0)
[(2, 97), (4, 95), (8, 91), (10, 89), (14, 85), (16, 83), (20, 79), (22, 77), (26, 73), (28, 71), (32, 67), (34, 65), (38, 61), (40, 59), (44, 55), (46, 53), (50, 49), (52, 47), (56, 43), (58, 41), (62, 37), (64, 35), (68, 31), (70, 29), (74, 25), (76, 23), (80, 19), (82, 17), (86, 13), (88, 11), (92, 7), (94, 5), (98, 1)]

실제로 python의 람다 식에는 여러 개의 문이 있을 수 있습니다.전체적으로 사소한 것은 아니지만 사용자의 예에서는 다음과 같이 작동합니다.

map(lambda x: x.sort() or x[1],lst)

각 문이 반환하지 않는지 또는 문을 (... 및 False)로 묶는지 확인해야 합니다.결과는 마지막 평가에서 반환되는 내용입니다.

예:

>>> f = (lambda : (print(1) and False) or (print(2) and False) or (print(3) and False))
>>> f()
1
2
3

파이썬에서 여러 문을 단일 문으로 결합하는 해키 방법은 "and" 키워드를 단락 연산자로 사용하는 것입니다.그런 다음 이 단일 문을 람다 식의 일부로 직접 사용할 수 있습니다.

이것은 bash와 같은 셸 언어에서 "&&"을 단락 연산자로 사용하는 것과 비슷합니다.

참고:함수를 래핑하여 참 값을 반환하는 함수 문을 항상 수정할 수 있습니다.

예:

def p2(*args):
    print(*args)
    return 1 # a true value

junky = lambda x, y: p2('hi') and p2('there') and p2(x) and p2(y)

junky("a", "b")

다시 생각해 보니, 많은 함수들이 성공하면 '0' 또는 '없음'을 반환하므로 'and' 대신 'or'를 사용하는 것이 더 나을 것입니다.그러면 위의 예에서 래퍼 함수를 제거할 수 있습니다.

junky = lambda x, y: print('hi') or print('there') or print(x) or print(y)

junky("a", "b")

'and' 연산은 첫 번째 0 반환 값에 도달할 때까지 식을 평가합니다. 그 후에는 단락됩니다. 1과 1과 0과 1은 1과 1과 0을 평가하고 1을 삭제합니다.

'또는' operation은 0이 아닌 첫 번째 반환 값에 도달할 때까지 식을 평가한 후 단락됩니다.

0 또는 0 또는 1 또는 0은 0 또는 0 또는 1을 평가하고 0을 삭제합니다.

다음과 같이 정렬된 함수를 사용합니다.

map(lambda x: sorted(x)[1],lst)

다음에서 begin() 사용하기: http://www.reddit.com/r/Python/comments/hms4z/ask_pyreddit_if_you_were_making_your_own/c1wycci

Python 3.2 (r32:88445, Mar 25 2011, 19:28:28) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]
>>> begin = lambda *args: args[-1]
>>> list(map(lambda x: begin(x.sort(), x[1]), lst))
[345, 465, 333]

이 긴 목록의 답을 읽는 동안, 저는 튜플을 남용하는 깔끔한 방법을 생각해냈습니다.

lambda x: (expr1(x), expr2(x), ..., result(x))[-1]

이렇게 하면 모든 식을 평가하고 마지막 식의 값을 반환하는 람다가 생성됩니다.그 표현들이 부작용이 있을 때만 말이 됩니다.print()또는sort().

과제 (일반인할당적일=하려면 )을 .:=할당된 값을 반환하는 연산자(Python 3.8에 추가됨):

lambda: (answer := 42, question := compute(answer), question)[-1]

그러나 위는 로컬 변수 할당에만 사용할 수 있습니다.하려면 예를들딕요할소당면합사니다야용해려하를을 .d.update({'key': 'value'})하지만 심지어는list유사한 옵션은 없습니다.l.__setitem__(index, value)사용해야 합니다.삭제할 때도 마찬가지입니다.는 표준컨너지를 지원합니다.x.pop(index)은 와동한등에 합니다.del x[item] 삭제된할 수 없는 에는 삭된값반만사수용경는을 해야 합니다.x.__delitem__(index)직접적으로.

변수에 글벌변영향미을치면반려합딕수니다야정해트가 .globals():

lambda: (g := globals(), g.__setitem__('answer', 42), g.__delitem__('question'), None)[-1]

리스트, 딕트 또는 심지어 집합을 튜플 대신 사용하여 표현식을 하나로 그룹화할 수 있지만 튜플이 더 빠르며(대부분 불변이기 때문에) 단점이 없는 것 같습니다.

또한 생산 코드에서 이 중 어떤 것도 사용하지 마십시오!예쁘게 해주세요!

영광스럽지만 무서운 해킹을 소개합니다.

import types

def _obj():
  return lambda: None

def LET(bindings, body, env=None):
  '''Introduce local bindings.
  ex: LET(('a', 1,
           'b', 2),
          lambda o: [o.a, o.b])
  gives: [1, 2]

  Bindings down the chain can depend on
  the ones above them through a lambda.
  ex: LET(('a', 1,
           'b', lambda o: o.a + 1),
          lambda o: o.b)
  gives: 2
  '''
  if len(bindings) == 0:
    return body(env)

  env = env or _obj()
  k, v = bindings[:2]
  if isinstance(v, types.FunctionType):
    v = v(env)

  setattr(env, k, v)
  return LET(bindings[2:], body, env)

이 이사할수있다를 할 수 있습니다.LET다음과 같은 형태:

map(lambda x: LET(('_', x.sort()),
                  lambda _: x[1]),
    lst)

이는 다음을 제공합니다.[345, 465, 333]

위에서 제공된 모든 솔루션을 분석한 후, 저는 다음과 같은 조합을 생각해 냈습니다. 이 조합은 저에게 가장 유용한 광고인 것 같습니다.

func = lambda *args, **kwargs: "return value" if [
    print("function 1..."),
    print("function n"),
    ["for loop" for x in range(10)]
] else None

아름답지 않나요?목록에 있는 항목이 있어야 하므로 참 값을 가집니다.그리고 또 다른 것은 C 스타일 코드처럼 보이기 위해 목록을 세트로 대체할 수 있지만, 이 경우 목록이 해시되지 않기 때문에 목록을 내부에 배치할 수 없습니다.

또는 람다를 사용하지 않고 목록 대신 생성기를 사용하려는 경우:

(sorted(col)[1] for col in lst)

실제로 람다에 여러 문을 사용할 수 있는 방법이 있습니다.제 솔루션은 다음과 같습니다.

lst = [[567,345,234],[253,465,756, 2345],[333,777,111, 555]]

x = lambda l: exec("l.sort(); return l[1]")

map(x, lst)

정렬이나 힙큐를 사용하는 대신 min과 index를 사용하여 O(n) 시간에 수행할 수 있습니다.

먼저 원래 목록의 최소값을 제외한 모든 항목의 새 목록을 만듭니다.

new_list = lst[:lst.index(min(lst))] + lst[lst.index(min(lst))+1:]

그런 다음 새 목록의 최소값을 가져옵니다.

second_smallest = min(new_list)

이제 모두 하나의 람다에 함께:

map(lambda x: min(x[:x.index(min(x))] + x[x.index(min(x))+1:]), lst)

네, 정말 못생겼지만 알고리즘적으로 저렴해야 합니다.또한 이 스레드의 일부 사용자는 목록 이해를 보고 싶어하기 때문에:

[min(x[:x.index(min(x))] + x[x.index(min(x))+1:]) for x in lst]

이것이 바로 그가 하는 것입니다.bind모나드의 함수는 다음에 사용됩니다.

bind함수 여러 람다를 하나의 람다로 결합할 수 있으며 각 람다는 문을 나타냅니다.

람다가 함수를 호출하도록 하는 다른 해결책을 제시하겠습니다.

def multiple_statements(x, y):
    print('hi')
    print('there')
    print(x)
    print(y)
    return 1

junky = lambda x, y: multiple_statements(x, y)

junky('a', 'b');

한 줄에 람다를 사용하는 방법으로 수업을 진행했습니다.

(code := lambda *exps, ret = None: [exp for exp in list(exps) + [ret]][-1])(Car := type("Car", (object,), {"__init__": lambda self, brand, color, electro = False: code(setattr(self, "brand", brand), setattr(self, "color", color), setattr(self, "electro", electro), setattr(self, "running", False)), "start": lambda self: code(code(print("Car was already running, it exploded.\nLMAO"), quit()) if self.running else None, setattr(self, "running", True), print("Vrooom")), "stop": lambda self: code(code(print("Car was off already, it exploded.\nLMAO"), quit()) if not self.running else None, setattr(self, "running", False), print("!Vrooom")), "repaint": lambda self, new_color: code(setattr(self, "color", new_color), print(f"Splash Splash, your car is now {new_color}")), "drive": lambda self: code(print("Vrooom") if self.running else code(print("Car was not started, it exploded.\nLMAO"), quit())), "is_on": lambda self: code(ret = self.running)}), car := Car("lamborghini", "#ff7400"), car.start(), car.drive(), car.is_on(), car.drive(), car.stop(), car.is_on(), car.stop())

더 읽기 쉬운 변형:

(
    code :=
    lambda *exps, ret = None:
    [
        exp
        for exp
        in list(exps) + [ret]
    ][-1]
)(

Car := type(
    "Car",
    (object,),
    {
        "__init__": lambda self, brand, color, electro = False: code(
            setattr(self, "brand", brand),
            setattr(self, "color", color),
            setattr(self, "electro", electro),
            setattr(self, "running", False)

        ),
        "start": lambda self: code(
            code(
                print("Car was already running, it exploded.\nLMAO"),
                quit()
            ) if self.running
            else None,
            setattr(self, "running", True),
            print("Vrooom")
        ),
        "stop": lambda self: code(
            code(
                print("Car was off already, it exploded.\nLMAO"),
                quit()
            ) if not self.running
            else None,
            setattr(self, "running", False),
            print("!Vrooom")
        ),
        "repaint": lambda self, new_color: code(
            setattr(self, "color", new_color),
            print(f"Splash Splash, your car is now {new_color}")        
        ),
        "drive": lambda self: code(
            print("Vrooom") if self.running
            else code(
                print("Car was not started, it exploded.\nLMAO"),
                quit()
            )
        ),
        "is_on": lambda self: code(
            ret = self.running
        )
    }
),

car := Car("lamborghini", "#ff7400"),
car.start(),
car.drive(),
car.is_on(),
car.drive(),
car.stop(),
car.is_on(),
car.stop()
)

여기서는 임의의 수의 인수를 사용하는 람다 함수를 사용하고 ","로 분할된 한 줄에 더 많은 식을 가질 수 있도록 기본 ret 인수를 없음으로 반환합니다.

나는 이것이 오래된 것이라는 것을 알지만 그것은 더 적절한 답을 가지고 있습니다.그래서, 나르시스 313의 대답에 근거하여, 저는 다음과 같은 작은 수정을 해야 합니다.

원본: map(lambdax: sorted(x)[1], lst)

실제: 지도(lambdax: (sorted(x)[1), lst))

이것이 작은 것이라는 것을 알고 있고 다소 분명하지만 누락된 브래킷 없이는 작동하지 않을 것입니다.람다 식은 여러 인수를 사용할 수 없지만 여러 작업의 목록/두 개를 사용할 수 있습니다.

예. 이렇게 정의한 다음 여러 개의 식을 다음으로 묶을 수 있습니다.

구성표 시작:

시작 = 람다 *x: x[-1]

공통 리스프 예후:

예후 = 람다 *x: x[-1]

람다 함수를 사용하지 않고 더 나은 솔루션이 있습니다.그러나 람다 함수를 정말로 사용하고 싶다면, 여기 여러 문을 처리할 수 있는 일반적인 솔루션이 있습니다: map(lambda x: x[1] if (x.sort() other x[1], lst)

당신은 그 진술서가 무엇을 반환하는지에 대해 별로 신경 쓰지 않습니다.

네, 가능합니다.아래 코드 조각을 시도해 보십시오.

x = [('human', 1), ('i', 2), ('am', 1), ('.', 1), ('love', 1), ('python', 3), ('', 1),
  ('run', 1), ('is', 2), ('robust', 1), ('hello', 1), ('spark', 2), ('to', 1), ('analysis', 2), ('on', 1), ('big', 1), ('data', 1), ('with', 1), ('analysis', 1), ('great', 1)
]

rdd_filter = rdd1_word_cnt_sum.filter(lambda x: 'python' in x or 'human' in x or 'big' in x)
rdd_filter.collect()

을 보이다lambda x:[f1(),f2()]여러 기능을 실행할 수 있는 효과lambda또한 코드를 축소하려는 경우 조건이 있을 경우 단일 행을 보여줍니다.

  • f1θ는 람다 함수일 수도 있습니다( 람다 내의 람다 또는 람다).내부 람다는 선택한 문/함수가 될 수 있습니다.
  • 'exec-statement 'exec-statement', 'exec-statement' .lambda x:[exec('a=[1]'),exec('b=2')]

touch(linux) 명령의 python 구현으로, 빈 파일이 이미 존재하지 않는 경우 빈 파일을 참조하십시오.

def touch(fpath):
    check= os.path.exists(fpath)
    (lambda fname1:[open(fname1,"w+",errors="ignore").write(""),print('Touched',fname1)] 
    if not check else None) (fpath)

입니다 [Touched 예정인쇄터치 [됨됨터치▁will]fpath ] 어에디fpath파일 경로가 입력으로 제공됩니다. 파일이 이미 존재하는 경우에는 아무 작업도 수행하지 않습니다.

그자리의 (lambda x: [ f(x), f2(x) ] ) (inp)<- 우리는 '를 통과합니다.inp에 입력한 바와 같이.lambda이 경우에 그것은fpath.

다음 세 가지 방법을 제안할 수 있습니다.

map(lambda x: sorted(x)[1], lst))
map(lambda x: min(x[:x.index(min(x))]+x[x.index(min(x))+1:]), lst)
map(lambda x: min([num for num in x if num != min(x)]), lst)

언급URL : https://stackoverflow.com/questions/862412/is-it-possible-to-have-multiple-statements-in-a-python-lambda-expression