map and filter function on array of lists
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
add a comment |
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
1
changingmap(lambda x: process_slide_index(x), tiles_index)
tolist(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 oflambda x: process_slide_index(x)
, justprocess_slide_index
suffices.
– Tomothy32
Nov 27 '18 at 5:13
add a comment |
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
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
python mapping
asked Nov 27 '18 at 5:04
Luís CostaLuís Costa
303218
303218
1
changingmap(lambda x: process_slide_index(x), tiles_index)
tolist(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 oflambda x: process_slide_index(x)
, justprocess_slide_index
suffices.
– Tomothy32
Nov 27 '18 at 5:13
add a comment |
1
changingmap(lambda x: process_slide_index(x), tiles_index)
tolist(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 oflambda x: process_slide_index(x)
, justprocess_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
add a comment |
3 Answers
3
active
oldest
votes
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.
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 withtiles = 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 forgenerators
if he wants to split the computation in 2. Anyway, the question referred tomap
andfilter
so comprehensions should be discussed in another thread.
– Netwave
Nov 27 '18 at 7:44
add a comment |
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)
What about then I want to pass additional parameters on my function? For example on myfiltered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)
, x is the object from tiles and thentile_size
andtile_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 likesamples = 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 likesamples = 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
add a comment |
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 replacesfilter()
. It's also a nice alternative tomap()
, 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 withmap
andfilter
, 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 tryingfiltered_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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 withtiles = 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 forgenerators
if he wants to split the computation in 2. Anyway, the question referred tomap
andfilter
so comprehensions should be discussed in another thread.
– Netwave
Nov 27 '18 at 7:44
add a comment |
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.
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 withtiles = 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 forgenerators
if he wants to split the computation in 2. Anyway, the question referred tomap
andfilter
so comprehensions should be discussed in another thread.
– Netwave
Nov 27 '18 at 7:44
add a comment |
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.
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.
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 withtiles = 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 forgenerators
if he wants to split the computation in 2. Anyway, the question referred tomap
andfilter
so comprehensions should be discussed in another thread.
– Netwave
Nov 27 '18 at 7:44
add a comment |
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 withtiles = 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 forgenerators
if he wants to split the computation in 2. Anyway, the question referred tomap
andfilter
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
add a comment |
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)
What about then I want to pass additional parameters on my function? For example on myfiltered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)
, x is the object from tiles and thentile_size
andtile_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 likesamples = 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 likesamples = 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
add a comment |
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)
What about then I want to pass additional parameters on my function? For example on myfiltered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)
, x is the object from tiles and thentile_size
andtile_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 likesamples = 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 likesamples = 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
add a comment |
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)
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)
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 myfiltered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)
, x is the object from tiles and thentile_size
andtile_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 likesamples = 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 likesamples = 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
add a comment |
What about then I want to pass additional parameters on my function? For example on myfiltered_tiles = filter(lambda x: keep_tile(x, tile_size, tissue_threshold), tiles)
, x is the object from tiles and thentile_size
andtile_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 likesamples = 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 likesamples = 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_size
and 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_size
and 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
add a comment |
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 replacesfilter()
. It's also a nice alternative tomap()
, 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 withmap
andfilter
, 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 tryingfiltered_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.
add a comment |
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 replacesfilter()
. It's also a nice alternative tomap()
, 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 withmap
andfilter
, 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 tryingfiltered_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.
add a comment |
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 replacesfilter()
. It's also a nice alternative tomap()
, 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 withmap
andfilter
, 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 tryingfiltered_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.
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 replacesfilter()
. It's also a nice alternative tomap()
, 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 withmap
andfilter
, 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 tryingfiltered_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.
answered Nov 27 '18 at 6:03
geofurbgeofurb
16319
16319
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
changing
map(lambda x: process_slide_index(x), tiles_index)
tolist(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)
, justprocess_slide_index
suffices.– Tomothy32
Nov 27 '18 at 5:13