1

Good evening, I would like to ask the community for help to understand the following, I have been experimenting with the functional programming method, and I have found basic functions such as map () reduce () filter (), but what I would like to know is what happens with the for cycles within functional programming.

For example, in this code I have to perform many for cycles to find a result:

test = {'one':1,'two':{'two-two':{'two-two-two':222,'three-three-three':333}},'three':3}

for i in test.items():
    if i[0]=="two":
        for s in i[1].items():
            if s[0] == "two-two":
                for a in s[1].items():
                    print(a[1])

Basically I do not know what would apply in this case, it would be a map () or a filter () or something else I hope you can help me

Venkatachalam
  • 16,288
  • 9
  • 49
  • 77
Mystic_Force
  • 263
  • 3
  • 12
  • [Related](https://stackoverflow.com/questions/10366374/what-is-the-pythonic-equivalent-to-the-fold-function-from-functional-program). – Tomas By Jan 02 '19 at 02:07
  • 2
    Do you mean "loops" when you are saying "cycles"? Because I don't think I've ever heard of "cycles" in this context. – Blckknght Jan 02 '19 at 02:50
  • 1
    Since this is a dictionary you can select by key, fopr example: `test['two']['two-two'].values()` – t.m.adam Jan 02 '19 at 02:54
  • Once you've used a for-loop, it is no longer functional programming – juanpa.arrivillaga Jan 02 '19 at 16:57
  • Result means, you want to get `1, 222,333,3` or just `222, 333`? In first case recursion is very useful even if there are a higher level nesting. – hygull Jan 02 '19 at 17:01

2 Answers2

1

I got, here you have used functional programming term to introduce the use of map(), filter() and reduce() in your code but you should not use it here for this scenario as functional programming refers to the implementation of your problem by using functions (modular design).

In your case, you cannot use filter(), reduce() to get the expected result as these functions does not provide you a flexible way to control the program's control.

You can try something like this but I don't want you to use that, you may get None if the condition is not satisfied in case of map(). Using filter() / reduce() does not make sense.

Here, I have tried to make it working as you expect.

>>> def f(tup):
...     items = []
...     if tup[0] == 'two':
...         for s in tup[1].items():
...             if s[0] == "two-two":
...                 for a in s[1].items():
...                     print(a[1])
...                     items.append(a[1])
...         return items
...     else:
...         return None
...
>>> test
{'one': 1, 'two': {'two-two': {'two-two-two': 222, 'three-three-three': 333}},
'three': 3}
>>>
>>> out = list(map(f, test.items()))
222
333
>>> out
[None, [222, 333], None]
>>>
>>> out[1]
[222, 333]
>>>

map(), filter() are bascially used to work on iterables like list, tuple, dictionary, set etc. and produce another iterables by performaing opeartions on items. filter() allows us to filter data (picking even numbers from a list).

reduce() is bascially used to work on iterables and reducing them to a single value (e.g. getting sum of list of numbers).

Initializations

>>> l = [9, 4, 3, 2, 1]
>>> d = {'first': 'Rishikesh', 'last': 'Agrawani'}
>>> t = (3, 4, 5)
>>>

Using map()

>>> # Using map()
...
>>> map_obj = map(lambda n: n ** 2, l)
>>> map_obj
<map object at 0x0000016DAF88B6D8>
>>>
>>> squares = list(map_obj)  # list(map(lambda n: n ** 2, l))
>>> squares
[81, 16, 9, 4, 1]
>>>
>>> details = {k + '-name': v for k, v in d.items()}
>>> details
{'first-name': 'Rishikesh', 'last-name': 'Agrawani'}
>>>
>>> details = dict(map(lambda tup: (tup[0] + '_name', tup[1]), d.items()))
>>> details
{'first_name': 'Rishikesh', 'last_name': 'Agrawani'}
>>>

Using filter()

>>> # Using filter() - let's filter even numbers from list
...
>>> filter_obj = filter(lambda n: n % 2 == 0, l)
>>> filter_obj
<filter object at 0x0000016DAF88B908>
>>>
>>> evens = list(filter_obj)
>>> evens
[4, 2]
>>>

Using reduce()

>>> # Using reduce() - finding sum of al numbers in a list
... # i.e. reducing list of values to a single value
...
>>> from functools import reduce
>>>
>>> total = reduce(lambda n1, n2: n1 + n2, l)
>>> total
19
>>>
hygull
  • 8,464
  • 2
  • 43
  • 52
-3

You can use a forEach() function to apply some callback function to each item in a collection

A basic implementation would look like this:

   function forEach(callback) {
      for(index=0;index<len_of_collection;index++) {
         callback(collection[index], index, collection);
      }
   }

You would need to make sure your collection implements this method for you to be able to call it from the collection like so:

some_collection.forEach(myCustomCallback)

Or inline:

some_collection.forEach(item => console.log(item))

Please excuse the JavaScript, I know the question was in Python but the concept is not language specific.

EDIT: https://www.geeksforgeeks.org/python-map-function/

map() function returns a list of the results after applying the given function to each item of a given iterable (list, tuple etc.)

Your example does not show modification. Therefore, map symantically would not be correct. If what you want is to apply some function without modification, explore options similar to forEach.

  • 1
    This seems to be more or less what the builtin `map` function already does. You don't need to reinvent the wheel to do it in Python. – Blckknght Jan 02 '19 at 05:07
  • Map modifies each entry in a collection. If you only want to apply some logic to each element without modifiying the existing collection, you would use a forEach. Unless it works differently in python, thats usually the definition of a map function. – Francisco Garcia Jan 02 '19 at 16:39
  • The question is related to Python's map(), filter() and reduce(). Your code is related to JavaScript's map(), filter() and reduce(). – hygull Jan 02 '19 at 16:55
  • @FranciscoGarcia absolutely incorrect, collections are not modified in-place by map. And anyway, `forEach` is not functional either, and `map` is *eminently* functional. – juanpa.arrivillaga Jan 02 '19 at 16:57
  • Python's `map()` only modifies its input if the given function is actually a method that modifies its object (e.g. `reverse` on a list). – nekomatic Jan 02 '19 at 16:59
  • @nekomatic exactly. `map` can be abused in Python by mapping a function with side-effects, which of course, will break the functional paradigm, but it is *designed* to be used in a functional manner. Of course, Python won't stop you from doing whatever you want. Python is not Haskell. – juanpa.arrivillaga Jan 02 '19 at 17:00
  • @juanpa.arrivallaga Ah i see. I was thinking the terminology was uniform across languages. Well, thanks for the clarification and sorry for the confusion. And i said each entry in the collection is modified, not the collection itself. the items are composed into a new list and returned. Thanks all for the clarification. Ill do more research before commenting – Francisco Garcia Jan 02 '19 at 19:48