Programing

파이썬 맵 및 기타 기능 도구 사용

crosscheck 2020. 7. 4. 10:45
반응형

파이썬 맵 및 기타 기능 도구 사용


이것은 꽤 n00bish이지만 파이썬에서 함수형 프로그래밍을 배우거나 이해하려고합니다. 다음 코드 :

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest(foo, bar):
    print foo, bar

map(maptest, foos, bars)

생산 :

1.0 1
2.0 2
3.0 3
4.0 None
5.0 None

Q. 파이썬에서 map 또는 다른 기능 도구를 사용하여 루프없이 다음을 생성하는 방법이 있습니까?

1.0 [1,2,3]
2.0 [1,2,3]
3.0 [1,2,3]
4.0 [1,2,3]
5.0 [1,2,3]

부수적으로 foo와 bar 사이에 의존성이있는 경우 구현이 어떻게 변경됩니까? 예 :

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]

인쇄 :

1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...

추신 : 나는 if, 루프 및 / 또는 생성기를 사용하여 순진하게 수행하는 방법을 알고 있지만 기능적 도구를 사용하여 동일한 것을 달성하는 방법을 배우고 싶습니다. maptest에 if 문을 추가하거나 maptest 내부의 막대에 다른 필터 맵을 적용하는 경우입니까?


가장 쉬운 방법은 bars다른 기능을 거치지 않고 다음에서 직접 액세스하는 것입니다 maptest.

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest(foo):
    print foo, bars

map(maptest, foos)

원래 maptest함수를 사용하면 다음에서 람다 함수를 사용할 수도 있습니다 map.

map((lambda foo: maptest(foo, bars)), foos)

다른 기능 언어에 익숙하십니까? 즉, 파이썬이 함수형 프로그래밍을 수행하는 방법을 배우려고합니까, 또는 함수형 프로그래밍에 대해 배우고 파이썬을 차량으로 사용하려고합니까?

또한 목록 이해력을 이해합니까?

map(f, sequence)

직접 다음과 같습니다 (*).

[f(x) for x in sequence]

실제로, 나는 map()파이썬 3.0에서 제거하기 위해 예정된 적이 있다고 생각 합니다.

map(f, sequence1, sequence2)

대부분 다음과 같습니다.

[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]

(시퀀스 길이가 다른 경우를 처리하는 방법에는 차이가 있습니다. 보시다시피 map(), 시퀀스 중 하나가 부족하면 없음을 채우고 zip()가장 짧은 시퀀스가 ​​중지되면 중지합니다)

따라서 특정 질문을 해결하기 위해 결과를 생성하려고합니다.

foos[0], bars
foos[1], bars
foos[2], bars
# etc.

You could do this by writing a function that takes a single argument and prints it, followed by bars:

def maptest(x):
     print x, bars
map(maptest, foos)

Alternatively, you could create a list that looks like this:

[bars, bars, bars, ] # etc.

and use your original maptest:

def maptest(x, y):
    print x, y

One way to do this would be to explicitely build the list beforehand:

barses = [bars] * len(foos)
map(maptest, foos, barses)

Alternatively, you could pull in the itertools module. itertools contains many clever functions that help you do functional-style lazy-evaluation programming in python. In this case, we want itertools.repeat, which will output its argument indefinitely as you iterate over it. This last fact means that if you do:

map(maptest, foos, itertools.repeat(bars))

you will get endless output, since map() keeps going as long as one of the arguments is still producing output. However, itertools.imap is just like map(), but stops as soon as the shortest iterable stops.

itertools.imap(maptest, foos, itertools.repeat(bars))

Hope this helps :-)

(*) It's a little different in python 3.0. There, map() essentially returns a generator expression.


Here's the solution you're looking for:

>>> foos = [1.0, 2.0, 3.0, 4.0, 5.0]
>>> bars = [1, 2, 3]
>>> [(x, bars) for x in foos]
[(1.0, [1, 2, 3]), (2.0, [1, 2, 3]), (3.0, [1, 2, 3]), (4.0, [1, 2, 3]), (5.0, [
1, 2, 3])]

I'd recommend using a list comprehension (the [(x, bars) for x in foos] part) over using map as it avoids the overhead of a function call on every iteration (which can be very significant). If you're just going to use it in a for loop, you'll get better speeds by using a generator comprehension:

>>> y = ((x, bars) for x in foos)
>>> for z in y:
...     print z
...
(1.0, [1, 2, 3])
(2.0, [1, 2, 3])
(3.0, [1, 2, 3])
(4.0, [1, 2, 3])
(5.0, [1, 2, 3])

The difference is that the generator comprehension is lazily loaded.

UPDATE In response to this comment:

Of course you know, that you don't copy bars, all entries are the same bars list. So if you modify any one of them (including original bars), you modify all of them.

I suppose this is a valid point. There are two solutions to this that I can think of. The most efficient is probably something like this:

tbars = tuple(bars)
[(x, tbars) for x in foos]

Since tuples are immutable, this will prevent bars from being modified through the results of this list comprehension (or generator comprehension if you go that route). If you really need to modify each and every one of the results, you can do this:

from copy import copy
[(x, copy(bars)) for x in foos]

However, this can be a bit expensive both in terms of memory usage and in speed, so I'd recommend against it unless you really need to add to each one of them.


Functional programming is about creating side-effect-free code.

map is a functional list transformation abstraction. You use it to take a sequence of something and turn it into a sequence of something else.

You are trying to use it as an iterator. Don't do that. :)

Here is an example of how you might use map to build the list you want. There are shorter solutions (I'd just use comprehensions), but this will help you understand what map does a bit better:

def my_transform_function(input):
    return [input, [1, 2, 3]]

new_list = map(my_transform, input_list)

Notice at this point, you've only done a data manipulation. Now you can print it:

for n,l in new_list:
    print n, ll

-- I'm not sure what you mean by 'without loops.' fp isn't about avoiding loops (you can't examine every item in a list without visiting each one). It's about avoiding side-effects, thus writing fewer bugs.


>>> from itertools import repeat
>>> for foo, bars in zip(foos, repeat(bars)):
...     print foo, bars
... 
1.0 [1, 2, 3]
2.0 [1, 2, 3]
3.0 [1, 2, 3]
4.0 [1, 2, 3]
5.0 [1, 2, 3]

import itertools

foos=[1.0, 2.0, 3.0, 4.0, 5.0]
bars=[1, 2, 3]

print zip(foos, itertools.cycle([bars]))

Here's an overview of the parameters to the map(function, *sequences) function:

  • function is the name of your function.
  • sequences is any number of sequences, which are usually lists or tuples. map will iterate over them simultaneously and give the current values to function. That's why the number of sequences should equal the number of parameters to your function.

It sounds like you're trying to iterate for some of function's parameters but keep others constant, and unfortunately map doesn't support that. I found an old proposal to add such a feature to Python, but the map construct is so clean and well-established that I doubt something like that will ever be implemented.

Use a workaround like global variables or list comprehensions, as others have suggested.


Would this do it?

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest2(bar):
  print bar

def maptest(foo):
  print foo
  map(maptest2, bars)

map(maptest, foos)

How about this:

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest(foo, bar):
    print foo, bar

map(maptest, foos, [bars]*len(foos))

참고URL : https://stackoverflow.com/questions/672172/using-python-map-and-other-functional-tools

반응형