map and filter function on array of lists












1















I want to map an array of lists like the one below using the function process_slide_index(x)



tiles_index:



[(1, 1024, 0, 16, 0, 0), (1, 1024, 0, 16, 0, 1), (1, 1024, 0, 16, 0, 2), (1, 1024, 0, 16, 0, 3), (1, 1024, 0, 16, 0, 4), (1, 1024, 0, 16, 0, 5), (1, 1024, 0, 16, 0, 6),...]


tiles:



tiles = map(lambda x: process_slide_index(x), tiles_index)


the map function:



def process_slide_index(tile_index):
print("PROCESS SLIDE INDEX")
slide_num, tile_size, overlap, zoom_level, col, row = tile_index
slide = open_slide(slide_num)
generator = create_tile_generator(slide, tile_size, overlap)
tile = np.asarray(generator.get_tile(zoom_level, (col, row)))

return (slide_num, tile)


I'm applying the map function but I don't seem to get inside my process_slide_index(tile_index) function.



I also want to filter some results given a function that returns True of False. But once again my function does not reach the filter function.



filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)


What am I doing wrong?



Regards



EDIT The only way I got to reach that checkpoint message PROCESS SLIDE INDEX was adding list(map(print, tiles)) after the tiles line. I was using this to try to debug and my prints started showing up. I'm pretty confused right now.










share|improve this question


















  • 1





    changing map(lambda x: process_slide_index(x), tiles_index) to list(map(lambda x: process_slide_index(x), tiles_index)) did the trick. Does this makes sense?

    – Luís Costa
    Nov 27 '18 at 5:13






  • 2





    BTW, instead of lambda x: process_slide_index(x), just process_slide_index suffices.

    – Tomothy32
    Nov 27 '18 at 5:13
















1















I want to map an array of lists like the one below using the function process_slide_index(x)



tiles_index:



[(1, 1024, 0, 16, 0, 0), (1, 1024, 0, 16, 0, 1), (1, 1024, 0, 16, 0, 2), (1, 1024, 0, 16, 0, 3), (1, 1024, 0, 16, 0, 4), (1, 1024, 0, 16, 0, 5), (1, 1024, 0, 16, 0, 6),...]


tiles:



tiles = map(lambda x: process_slide_index(x), tiles_index)


the map function:



def process_slide_index(tile_index):
print("PROCESS SLIDE INDEX")
slide_num, tile_size, overlap, zoom_level, col, row = tile_index
slide = open_slide(slide_num)
generator = create_tile_generator(slide, tile_size, overlap)
tile = np.asarray(generator.get_tile(zoom_level, (col, row)))

return (slide_num, tile)


I'm applying the map function but I don't seem to get inside my process_slide_index(tile_index) function.



I also want to filter some results given a function that returns True of False. But once again my function does not reach the filter function.



filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)


What am I doing wrong?



Regards



EDIT The only way I got to reach that checkpoint message PROCESS SLIDE INDEX was adding list(map(print, tiles)) after the tiles line. I was using this to try to debug and my prints started showing up. I'm pretty confused right now.










share|improve this question


















  • 1





    changing map(lambda x: process_slide_index(x), tiles_index) to list(map(lambda x: process_slide_index(x), tiles_index)) did the trick. Does this makes sense?

    – Luís Costa
    Nov 27 '18 at 5:13






  • 2





    BTW, instead of lambda x: process_slide_index(x), just process_slide_index suffices.

    – Tomothy32
    Nov 27 '18 at 5:13














1












1








1








I want to map an array of lists like the one below using the function process_slide_index(x)



tiles_index:



[(1, 1024, 0, 16, 0, 0), (1, 1024, 0, 16, 0, 1), (1, 1024, 0, 16, 0, 2), (1, 1024, 0, 16, 0, 3), (1, 1024, 0, 16, 0, 4), (1, 1024, 0, 16, 0, 5), (1, 1024, 0, 16, 0, 6),...]


tiles:



tiles = map(lambda x: process_slide_index(x), tiles_index)


the map function:



def process_slide_index(tile_index):
print("PROCESS SLIDE INDEX")
slide_num, tile_size, overlap, zoom_level, col, row = tile_index
slide = open_slide(slide_num)
generator = create_tile_generator(slide, tile_size, overlap)
tile = np.asarray(generator.get_tile(zoom_level, (col, row)))

return (slide_num, tile)


I'm applying the map function but I don't seem to get inside my process_slide_index(tile_index) function.



I also want to filter some results given a function that returns True of False. But once again my function does not reach the filter function.



filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)


What am I doing wrong?



Regards



EDIT The only way I got to reach that checkpoint message PROCESS SLIDE INDEX was adding list(map(print, tiles)) after the tiles line. I was using this to try to debug and my prints started showing up. I'm pretty confused right now.










share|improve this question














I want to map an array of lists like the one below using the function process_slide_index(x)



tiles_index:



[(1, 1024, 0, 16, 0, 0), (1, 1024, 0, 16, 0, 1), (1, 1024, 0, 16, 0, 2), (1, 1024, 0, 16, 0, 3), (1, 1024, 0, 16, 0, 4), (1, 1024, 0, 16, 0, 5), (1, 1024, 0, 16, 0, 6),...]


tiles:



tiles = map(lambda x: process_slide_index(x), tiles_index)


the map function:



def process_slide_index(tile_index):
print("PROCESS SLIDE INDEX")
slide_num, tile_size, overlap, zoom_level, col, row = tile_index
slide = open_slide(slide_num)
generator = create_tile_generator(slide, tile_size, overlap)
tile = np.asarray(generator.get_tile(zoom_level, (col, row)))

return (slide_num, tile)


I'm applying the map function but I don't seem to get inside my process_slide_index(tile_index) function.



I also want to filter some results given a function that returns True of False. But once again my function does not reach the filter function.



filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)


What am I doing wrong?



Regards



EDIT The only way I got to reach that checkpoint message PROCESS SLIDE INDEX was adding list(map(print, tiles)) after the tiles line. I was using this to try to debug and my prints started showing up. I'm pretty confused right now.







python mapping






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 27 '18 at 5:04









Luís CostaLuís Costa

303218




303218








  • 1





    changing map(lambda x: process_slide_index(x), tiles_index) to list(map(lambda x: process_slide_index(x), tiles_index)) did the trick. Does this makes sense?

    – Luís Costa
    Nov 27 '18 at 5:13






  • 2





    BTW, instead of lambda x: process_slide_index(x), just process_slide_index suffices.

    – Tomothy32
    Nov 27 '18 at 5:13














  • 1





    changing map(lambda x: process_slide_index(x), tiles_index) to list(map(lambda x: process_slide_index(x), tiles_index)) did the trick. Does this makes sense?

    – Luís Costa
    Nov 27 '18 at 5:13






  • 2





    BTW, instead of lambda x: process_slide_index(x), just process_slide_index suffices.

    – Tomothy32
    Nov 27 '18 at 5:13








1




1





changing map(lambda x: process_slide_index(x), tiles_index) to list(map(lambda x: process_slide_index(x), tiles_index)) did the trick. Does this makes sense?

– Luís Costa
Nov 27 '18 at 5:13





changing map(lambda x: process_slide_index(x), tiles_index) to list(map(lambda x: process_slide_index(x), tiles_index)) did the trick. Does this makes sense?

– Luís Costa
Nov 27 '18 at 5:13




2




2





BTW, instead of lambda x: process_slide_index(x), just process_slide_index suffices.

– Tomothy32
Nov 27 '18 at 5:13





BTW, instead of lambda x: process_slide_index(x), just process_slide_index suffices.

– Tomothy32
Nov 27 '18 at 5:13












3 Answers
3






active

oldest

votes


















3














You are using python3, in python2 map and filter return a list, but in python3 they return an object that you have to consume to get the values:



>>> l = list(range(10))
>>> def foo(x):
... print(x)
... return x+1
...
>>> map(foo, l)
<map object at 0x7f69728da828>


For consuming this object, you can use list for example. Notice how the print is called this time:



>>> list(map(foo, l))
0
1
2
3
4
5
6
7
8
9
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


This objects are lazy, that means that they yield the values one by one. Check the differences when using them as iterators in a for loop:



>>> for e in map(foo, l):
... print(e)
...
0
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10


Using list does the same, but stores each taken value in that list.






share|improve this answer


























  • read my post comment. I guess it complements your answer. Or maybe not.

    – Luís Costa
    Nov 27 '18 at 5:14











  • Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

    – Luís Costa
    Nov 27 '18 at 5:21











  • Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

    – geofurb
    Nov 27 '18 at 7:03











  • @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

    – Netwave
    Nov 27 '18 at 7:44



















1














You should remove the lambda from your map call. map will call the function provided in the first argument and in your case you have provided a wrapper function for the function you actually want to call.



tiles = map(process_slide_index, tiles_index)





share|improve this answer
























  • What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

    – Luís Costa
    Nov 27 '18 at 5:19











  • It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

    – B. Morris
    Nov 27 '18 at 5:30













  • Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

    – Luís Costa
    Nov 27 '18 at 5:48






  • 1





    It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

    – B. Morris
    Nov 27 '18 at 5:54











  • Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

    – Luís Costa
    Nov 27 '18 at 5:56





















0














TL;DR -




  • List comprehension can do a lot of things you might want here. [x for x in mylist if x > y] is a powerful expression that more than replaces filter(). It's also a nice alternative to map(), and is much more efficient than using a lambda expression. It also spits out a list instead of a generator, which is probably preferable in your case. (If you're dealing with huge streams of data, you might want to stick with map and filter, because with generators you don't have to keep the whole thing in RAM, you can work out one value at a time.) If you like this suggestion and want to skip the talk, I give you the code in 2b.


  • Don't write a lambda expression for a function that already exists! Lambda expressions are stand-in functions where you haven't defined one. They're much slower and have some weird behaviors. Avoid them where possible. You could replace the lambda in your map() call with the function itself: tiles = map(process_slide_index, tiles_index)



 



The long version:



There are two problems, both are pretty easy to fix. First one is more of a style/efficiency thing, but it'll save you some obscure headaches, too:



1. Instead of creating a lambda expression, it's best to use the function you already went to the work of defining!
tiles = map(process_slide_index, tiles_index) does the job just fine, and behaves better.



2. You should probably switch to list comprehensions. Why? Because map() and filter() are uglier and they're slower if you have to use a lambda or want to convert the output to a list afterwards. Still, if you insist on using map() and filter()...



2a. When you need to pass multiple arguments into a function for map, try functools.partial if you know many of the values ahead of time. I think it's an error in your logic when you're trying
filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)

What you're telling it to do is to call keep_tile() on a vector of [x for x in tiles] while holding tile_size and tissue_threshold constant.



If this is the intended behavior, try import functools and use functools.partial(keep_tile, tile_size, tissue_threshold).

Note: Using functools.partial requires that any variables you pass to the partial function are the rightmost arguments, so you'd have to rewrite the function header as def keep_tile(tile_size, tissue_threshold, tiles): instead of def keep_tile(tiles, tile_size, tissue_threshold):. (See that we again manage to avoid a lambda expression!)



If that isn't the intended behavior, and you wanted each of those values to change with every call, just pass a tuple in! filter(keep_tile, (tile, tile_size, tissue_threshold))). If you just want the tile variable from this, you can use a list comprehension:
[x[0] for x in filter(keep_tile, (tile, tile_size, tissue_threshold)))] (Again, with no lambdas.) However, since we're already doing a list comprehension here, you might want to try the solution in 2b.



2b. It's generally faster and cleaner on later Python releases just to use a list comprehension such as [x[0] for x in tiles if keep_tile(*x)]. (Or, if you meant to hold the other two values constant, you could use [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)].) Any time you're just going to read that map() or filter()'s output into a list afterwards, you should probably have used a list comprehension instead. At this point map() and filter() are really only useful for streaming results through a pipeline, or for async routines.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53493058%2fmap-and-filter-function-on-array-of-lists%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    You are using python3, in python2 map and filter return a list, but in python3 they return an object that you have to consume to get the values:



    >>> l = list(range(10))
    >>> def foo(x):
    ... print(x)
    ... return x+1
    ...
    >>> map(foo, l)
    <map object at 0x7f69728da828>


    For consuming this object, you can use list for example. Notice how the print is called this time:



    >>> list(map(foo, l))
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


    This objects are lazy, that means that they yield the values one by one. Check the differences when using them as iterators in a for loop:



    >>> for e in map(foo, l):
    ... print(e)
    ...
    0
    1
    1
    2
    2
    3
    3
    4
    4
    5
    5
    6
    6
    7
    7
    8
    8
    9
    9
    10


    Using list does the same, but stores each taken value in that list.






    share|improve this answer


























    • read my post comment. I guess it complements your answer. Or maybe not.

      – Luís Costa
      Nov 27 '18 at 5:14











    • Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

      – Luís Costa
      Nov 27 '18 at 5:21











    • Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

      – geofurb
      Nov 27 '18 at 7:03











    • @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

      – Netwave
      Nov 27 '18 at 7:44
















    3














    You are using python3, in python2 map and filter return a list, but in python3 they return an object that you have to consume to get the values:



    >>> l = list(range(10))
    >>> def foo(x):
    ... print(x)
    ... return x+1
    ...
    >>> map(foo, l)
    <map object at 0x7f69728da828>


    For consuming this object, you can use list for example. Notice how the print is called this time:



    >>> list(map(foo, l))
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


    This objects are lazy, that means that they yield the values one by one. Check the differences when using them as iterators in a for loop:



    >>> for e in map(foo, l):
    ... print(e)
    ...
    0
    1
    1
    2
    2
    3
    3
    4
    4
    5
    5
    6
    6
    7
    7
    8
    8
    9
    9
    10


    Using list does the same, but stores each taken value in that list.






    share|improve this answer


























    • read my post comment. I guess it complements your answer. Or maybe not.

      – Luís Costa
      Nov 27 '18 at 5:14











    • Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

      – Luís Costa
      Nov 27 '18 at 5:21











    • Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

      – geofurb
      Nov 27 '18 at 7:03











    • @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

      – Netwave
      Nov 27 '18 at 7:44














    3












    3








    3







    You are using python3, in python2 map and filter return a list, but in python3 they return an object that you have to consume to get the values:



    >>> l = list(range(10))
    >>> def foo(x):
    ... print(x)
    ... return x+1
    ...
    >>> map(foo, l)
    <map object at 0x7f69728da828>


    For consuming this object, you can use list for example. Notice how the print is called this time:



    >>> list(map(foo, l))
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


    This objects are lazy, that means that they yield the values one by one. Check the differences when using them as iterators in a for loop:



    >>> for e in map(foo, l):
    ... print(e)
    ...
    0
    1
    1
    2
    2
    3
    3
    4
    4
    5
    5
    6
    6
    7
    7
    8
    8
    9
    9
    10


    Using list does the same, but stores each taken value in that list.






    share|improve this answer















    You are using python3, in python2 map and filter return a list, but in python3 they return an object that you have to consume to get the values:



    >>> l = list(range(10))
    >>> def foo(x):
    ... print(x)
    ... return x+1
    ...
    >>> map(foo, l)
    <map object at 0x7f69728da828>


    For consuming this object, you can use list for example. Notice how the print is called this time:



    >>> list(map(foo, l))
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


    This objects are lazy, that means that they yield the values one by one. Check the differences when using them as iterators in a for loop:



    >>> for e in map(foo, l):
    ... print(e)
    ...
    0
    1
    1
    2
    2
    3
    3
    4
    4
    5
    5
    6
    6
    7
    7
    8
    8
    9
    9
    10


    Using list does the same, but stores each taken value in that list.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 27 '18 at 5:19

























    answered Nov 27 '18 at 5:12









    NetwaveNetwave

    12.5k22144




    12.5k22144













    • read my post comment. I guess it complements your answer. Or maybe not.

      – Luís Costa
      Nov 27 '18 at 5:14











    • Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

      – Luís Costa
      Nov 27 '18 at 5:21











    • Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

      – geofurb
      Nov 27 '18 at 7:03











    • @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

      – Netwave
      Nov 27 '18 at 7:44



















    • read my post comment. I guess it complements your answer. Or maybe not.

      – Luís Costa
      Nov 27 '18 at 5:14











    • Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

      – Luís Costa
      Nov 27 '18 at 5:21











    • Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

      – geofurb
      Nov 27 '18 at 7:03











    • @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

      – Netwave
      Nov 27 '18 at 7:44

















    read my post comment. I guess it complements your answer. Or maybe not.

    – Luís Costa
    Nov 27 '18 at 5:14





    read my post comment. I guess it complements your answer. Or maybe not.

    – Luís Costa
    Nov 27 '18 at 5:14













    Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

    – Luís Costa
    Nov 27 '18 at 5:21





    Thank you very much. I'm going test with tiles = list(map(lambda x: process_slide_index(x), tiles_index))

    – Luís Costa
    Nov 27 '18 at 5:21













    Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

    – geofurb
    Nov 27 '18 at 7:03





    Use a list comprehension instead. It'll make your life so much easier and your code so much faster than those lambdas.

    – geofurb
    Nov 27 '18 at 7:03













    @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

    – Netwave
    Nov 27 '18 at 7:44





    @geofurb, Even if you are correct, you are making a lot assumptions there. In this case, the usage would go for generators if he wants to split the computation in 2. Anyway, the question referred to map and filter so comprehensions should be discussed in another thread.

    – Netwave
    Nov 27 '18 at 7:44













    1














    You should remove the lambda from your map call. map will call the function provided in the first argument and in your case you have provided a wrapper function for the function you actually want to call.



    tiles = map(process_slide_index, tiles_index)





    share|improve this answer
























    • What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

      – Luís Costa
      Nov 27 '18 at 5:19











    • It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

      – B. Morris
      Nov 27 '18 at 5:30













    • Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

      – Luís Costa
      Nov 27 '18 at 5:48






    • 1





      It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

      – B. Morris
      Nov 27 '18 at 5:54











    • Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

      – Luís Costa
      Nov 27 '18 at 5:56


















    1














    You should remove the lambda from your map call. map will call the function provided in the first argument and in your case you have provided a wrapper function for the function you actually want to call.



    tiles = map(process_slide_index, tiles_index)





    share|improve this answer
























    • What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

      – Luís Costa
      Nov 27 '18 at 5:19











    • It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

      – B. Morris
      Nov 27 '18 at 5:30













    • Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

      – Luís Costa
      Nov 27 '18 at 5:48






    • 1





      It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

      – B. Morris
      Nov 27 '18 at 5:54











    • Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

      – Luís Costa
      Nov 27 '18 at 5:56
















    1












    1








    1







    You should remove the lambda from your map call. map will call the function provided in the first argument and in your case you have provided a wrapper function for the function you actually want to call.



    tiles = map(process_slide_index, tiles_index)





    share|improve this answer













    You should remove the lambda from your map call. map will call the function provided in the first argument and in your case you have provided a wrapper function for the function you actually want to call.



    tiles = map(process_slide_index, tiles_index)






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 27 '18 at 5:15









    B. MorrisB. Morris

    1718




    1718













    • What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

      – Luís Costa
      Nov 27 '18 at 5:19











    • It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

      – B. Morris
      Nov 27 '18 at 5:30













    • Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

      – Luís Costa
      Nov 27 '18 at 5:48






    • 1





      It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

      – B. Morris
      Nov 27 '18 at 5:54











    • Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

      – Luís Costa
      Nov 27 '18 at 5:56





















    • What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

      – Luís Costa
      Nov 27 '18 at 5:19











    • It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

      – B. Morris
      Nov 27 '18 at 5:30













    • Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

      – Luís Costa
      Nov 27 '18 at 5:48






    • 1





      It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

      – B. Morris
      Nov 27 '18 at 5:54











    • Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

      – Luís Costa
      Nov 27 '18 at 5:56



















    What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

    – Luís Costa
    Nov 27 '18 at 5:19





    What about then I want to pass additional parameters on my function? For example on my filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles), x is the object from tiles and then tile_sizeand tile_threshold

    – Luís Costa
    Nov 27 '18 at 5:19













    It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

    – B. Morris
    Nov 27 '18 at 5:30







    It can be easier (and I have heard more efficient, too) to just use list comprehension in that case: filtered_tiles = [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)]

    – B. Morris
    Nov 27 '18 at 5:30















    Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

    – Luís Costa
    Nov 27 '18 at 5:48





    Thank you very much then. Going to test it. I know it is out of topic, but do you have any idea how can I flatter a list of arrays? Something like samples = filtered_tiles.flatMap(lambda tile: process_tile(tile, sample_size, grayscale))

    – Luís Costa
    Nov 27 '18 at 5:48




    1




    1





    It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

    – B. Morris
    Nov 27 '18 at 5:54





    It would probably be helpful to give an example of what you want to end up with, and probably as a new question.

    – B. Morris
    Nov 27 '18 at 5:54













    Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

    – Luís Costa
    Nov 27 '18 at 5:56







    Yes, you are right. But about what you suggested. Imagine I have something like samples = list(map(lambda x: process_tile(x, sample_size, grayscale), filtered_tiles)). It is possible to still use your approach?

    – Luís Costa
    Nov 27 '18 at 5:56













    0














    TL;DR -




    • List comprehension can do a lot of things you might want here. [x for x in mylist if x > y] is a powerful expression that more than replaces filter(). It's also a nice alternative to map(), and is much more efficient than using a lambda expression. It also spits out a list instead of a generator, which is probably preferable in your case. (If you're dealing with huge streams of data, you might want to stick with map and filter, because with generators you don't have to keep the whole thing in RAM, you can work out one value at a time.) If you like this suggestion and want to skip the talk, I give you the code in 2b.


    • Don't write a lambda expression for a function that already exists! Lambda expressions are stand-in functions where you haven't defined one. They're much slower and have some weird behaviors. Avoid them where possible. You could replace the lambda in your map() call with the function itself: tiles = map(process_slide_index, tiles_index)



     



    The long version:



    There are two problems, both are pretty easy to fix. First one is more of a style/efficiency thing, but it'll save you some obscure headaches, too:



    1. Instead of creating a lambda expression, it's best to use the function you already went to the work of defining!
    tiles = map(process_slide_index, tiles_index) does the job just fine, and behaves better.



    2. You should probably switch to list comprehensions. Why? Because map() and filter() are uglier and they're slower if you have to use a lambda or want to convert the output to a list afterwards. Still, if you insist on using map() and filter()...



    2a. When you need to pass multiple arguments into a function for map, try functools.partial if you know many of the values ahead of time. I think it's an error in your logic when you're trying
    filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)

    What you're telling it to do is to call keep_tile() on a vector of [x for x in tiles] while holding tile_size and tissue_threshold constant.



    If this is the intended behavior, try import functools and use functools.partial(keep_tile, tile_size, tissue_threshold).

    Note: Using functools.partial requires that any variables you pass to the partial function are the rightmost arguments, so you'd have to rewrite the function header as def keep_tile(tile_size, tissue_threshold, tiles): instead of def keep_tile(tiles, tile_size, tissue_threshold):. (See that we again manage to avoid a lambda expression!)



    If that isn't the intended behavior, and you wanted each of those values to change with every call, just pass a tuple in! filter(keep_tile, (tile, tile_size, tissue_threshold))). If you just want the tile variable from this, you can use a list comprehension:
    [x[0] for x in filter(keep_tile, (tile, tile_size, tissue_threshold)))] (Again, with no lambdas.) However, since we're already doing a list comprehension here, you might want to try the solution in 2b.



    2b. It's generally faster and cleaner on later Python releases just to use a list comprehension such as [x[0] for x in tiles if keep_tile(*x)]. (Or, if you meant to hold the other two values constant, you could use [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)].) Any time you're just going to read that map() or filter()'s output into a list afterwards, you should probably have used a list comprehension instead. At this point map() and filter() are really only useful for streaming results through a pipeline, or for async routines.






    share|improve this answer




























      0














      TL;DR -




      • List comprehension can do a lot of things you might want here. [x for x in mylist if x > y] is a powerful expression that more than replaces filter(). It's also a nice alternative to map(), and is much more efficient than using a lambda expression. It also spits out a list instead of a generator, which is probably preferable in your case. (If you're dealing with huge streams of data, you might want to stick with map and filter, because with generators you don't have to keep the whole thing in RAM, you can work out one value at a time.) If you like this suggestion and want to skip the talk, I give you the code in 2b.


      • Don't write a lambda expression for a function that already exists! Lambda expressions are stand-in functions where you haven't defined one. They're much slower and have some weird behaviors. Avoid them where possible. You could replace the lambda in your map() call with the function itself: tiles = map(process_slide_index, tiles_index)



       



      The long version:



      There are two problems, both are pretty easy to fix. First one is more of a style/efficiency thing, but it'll save you some obscure headaches, too:



      1. Instead of creating a lambda expression, it's best to use the function you already went to the work of defining!
      tiles = map(process_slide_index, tiles_index) does the job just fine, and behaves better.



      2. You should probably switch to list comprehensions. Why? Because map() and filter() are uglier and they're slower if you have to use a lambda or want to convert the output to a list afterwards. Still, if you insist on using map() and filter()...



      2a. When you need to pass multiple arguments into a function for map, try functools.partial if you know many of the values ahead of time. I think it's an error in your logic when you're trying
      filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)

      What you're telling it to do is to call keep_tile() on a vector of [x for x in tiles] while holding tile_size and tissue_threshold constant.



      If this is the intended behavior, try import functools and use functools.partial(keep_tile, tile_size, tissue_threshold).

      Note: Using functools.partial requires that any variables you pass to the partial function are the rightmost arguments, so you'd have to rewrite the function header as def keep_tile(tile_size, tissue_threshold, tiles): instead of def keep_tile(tiles, tile_size, tissue_threshold):. (See that we again manage to avoid a lambda expression!)



      If that isn't the intended behavior, and you wanted each of those values to change with every call, just pass a tuple in! filter(keep_tile, (tile, tile_size, tissue_threshold))). If you just want the tile variable from this, you can use a list comprehension:
      [x[0] for x in filter(keep_tile, (tile, tile_size, tissue_threshold)))] (Again, with no lambdas.) However, since we're already doing a list comprehension here, you might want to try the solution in 2b.



      2b. It's generally faster and cleaner on later Python releases just to use a list comprehension such as [x[0] for x in tiles if keep_tile(*x)]. (Or, if you meant to hold the other two values constant, you could use [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)].) Any time you're just going to read that map() or filter()'s output into a list afterwards, you should probably have used a list comprehension instead. At this point map() and filter() are really only useful for streaming results through a pipeline, or for async routines.






      share|improve this answer


























        0












        0








        0







        TL;DR -




        • List comprehension can do a lot of things you might want here. [x for x in mylist if x > y] is a powerful expression that more than replaces filter(). It's also a nice alternative to map(), and is much more efficient than using a lambda expression. It also spits out a list instead of a generator, which is probably preferable in your case. (If you're dealing with huge streams of data, you might want to stick with map and filter, because with generators you don't have to keep the whole thing in RAM, you can work out one value at a time.) If you like this suggestion and want to skip the talk, I give you the code in 2b.


        • Don't write a lambda expression for a function that already exists! Lambda expressions are stand-in functions where you haven't defined one. They're much slower and have some weird behaviors. Avoid them where possible. You could replace the lambda in your map() call with the function itself: tiles = map(process_slide_index, tiles_index)



         



        The long version:



        There are two problems, both are pretty easy to fix. First one is more of a style/efficiency thing, but it'll save you some obscure headaches, too:



        1. Instead of creating a lambda expression, it's best to use the function you already went to the work of defining!
        tiles = map(process_slide_index, tiles_index) does the job just fine, and behaves better.



        2. You should probably switch to list comprehensions. Why? Because map() and filter() are uglier and they're slower if you have to use a lambda or want to convert the output to a list afterwards. Still, if you insist on using map() and filter()...



        2a. When you need to pass multiple arguments into a function for map, try functools.partial if you know many of the values ahead of time. I think it's an error in your logic when you're trying
        filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)

        What you're telling it to do is to call keep_tile() on a vector of [x for x in tiles] while holding tile_size and tissue_threshold constant.



        If this is the intended behavior, try import functools and use functools.partial(keep_tile, tile_size, tissue_threshold).

        Note: Using functools.partial requires that any variables you pass to the partial function are the rightmost arguments, so you'd have to rewrite the function header as def keep_tile(tile_size, tissue_threshold, tiles): instead of def keep_tile(tiles, tile_size, tissue_threshold):. (See that we again manage to avoid a lambda expression!)



        If that isn't the intended behavior, and you wanted each of those values to change with every call, just pass a tuple in! filter(keep_tile, (tile, tile_size, tissue_threshold))). If you just want the tile variable from this, you can use a list comprehension:
        [x[0] for x in filter(keep_tile, (tile, tile_size, tissue_threshold)))] (Again, with no lambdas.) However, since we're already doing a list comprehension here, you might want to try the solution in 2b.



        2b. It's generally faster and cleaner on later Python releases just to use a list comprehension such as [x[0] for x in tiles if keep_tile(*x)]. (Or, if you meant to hold the other two values constant, you could use [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)].) Any time you're just going to read that map() or filter()'s output into a list afterwards, you should probably have used a list comprehension instead. At this point map() and filter() are really only useful for streaming results through a pipeline, or for async routines.






        share|improve this answer













        TL;DR -




        • List comprehension can do a lot of things you might want here. [x for x in mylist if x > y] is a powerful expression that more than replaces filter(). It's also a nice alternative to map(), and is much more efficient than using a lambda expression. It also spits out a list instead of a generator, which is probably preferable in your case. (If you're dealing with huge streams of data, you might want to stick with map and filter, because with generators you don't have to keep the whole thing in RAM, you can work out one value at a time.) If you like this suggestion and want to skip the talk, I give you the code in 2b.


        • Don't write a lambda expression for a function that already exists! Lambda expressions are stand-in functions where you haven't defined one. They're much slower and have some weird behaviors. Avoid them where possible. You could replace the lambda in your map() call with the function itself: tiles = map(process_slide_index, tiles_index)



         



        The long version:



        There are two problems, both are pretty easy to fix. First one is more of a style/efficiency thing, but it'll save you some obscure headaches, too:



        1. Instead of creating a lambda expression, it's best to use the function you already went to the work of defining!
        tiles = map(process_slide_index, tiles_index) does the job just fine, and behaves better.



        2. You should probably switch to list comprehensions. Why? Because map() and filter() are uglier and they're slower if you have to use a lambda or want to convert the output to a list afterwards. Still, if you insist on using map() and filter()...



        2a. When you need to pass multiple arguments into a function for map, try functools.partial if you know many of the values ahead of time. I think it's an error in your logic when you're trying
        filtered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)

        What you're telling it to do is to call keep_tile() on a vector of [x for x in tiles] while holding tile_size and tissue_threshold constant.



        If this is the intended behavior, try import functools and use functools.partial(keep_tile, tile_size, tissue_threshold).

        Note: Using functools.partial requires that any variables you pass to the partial function are the rightmost arguments, so you'd have to rewrite the function header as def keep_tile(tile_size, tissue_threshold, tiles): instead of def keep_tile(tiles, tile_size, tissue_threshold):. (See that we again manage to avoid a lambda expression!)



        If that isn't the intended behavior, and you wanted each of those values to change with every call, just pass a tuple in! filter(keep_tile, (tile, tile_size, tissue_threshold))). If you just want the tile variable from this, you can use a list comprehension:
        [x[0] for x in filter(keep_tile, (tile, tile_size, tissue_threshold)))] (Again, with no lambdas.) However, since we're already doing a list comprehension here, you might want to try the solution in 2b.



        2b. It's generally faster and cleaner on later Python releases just to use a list comprehension such as [x[0] for x in tiles if keep_tile(*x)]. (Or, if you meant to hold the other two values constant, you could use [x for x in tiles if keep_tile(x, tile_size, tissue_threshold)].) Any time you're just going to read that map() or filter()'s output into a list afterwards, you should probably have used a list comprehension instead. At this point map() and filter() are really only useful for streaming results through a pipeline, or for async routines.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 6:03









        geofurbgeofurb

        16319




        16319






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53493058%2fmap-and-filter-function-on-array-of-lists%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Contact image not getting when fetch all contact list from iPhone by CNContact

            count number of partitions of a set with n elements into k subsets

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks