|
Hello,
I was trying to create a flattened list of dictionary values where each
value is a list, and I was hoping to do this in some neat functionally
style, in some brief, throwaway line so that it would assume the
insignificance that it deserves in the grand scheme of my program.
I had in mind something like this:
>>interleave([1, 2, 3], [4,5], [7, 8, 9])
[1, 4, 7, 2, 5, 8, 3, 9]
I played for a while with zip(), [some newfangled python keyword, that
I was truly shocked to find has been hiding at the bottom of the list
built in functions since version 2.0], before giving up and going back
to trusty old map(), long celebrated for making code hard to read:
>>map(None, [1, 2, 3], [4,5], [7, 8, 9])
[(1, 4, 7), (2, 5, 8), (3, None, 9)]
This is basically it. It then becomes:
>>filter(None, flatten(map(None, [1, 2, 3], [4,5], [7, 8, 9])))
[1, 4, 7, 2, 5, 8, 3, 9]
filter(None, - my brain parses that automatically now. This is not so
bad. Flatten is snitched from ASPN/Cookbook/Python/Recipe/363051,
thank you Jordan Callicoat, Mike C. Fletcher:
def flatten(l, ltypes=(list, tuple)):
i = 0
while (i < len(l)):
while (isinstance(l[i], ltypes)):
l[i:i+1] = list(l[i])
i += 1
return l
Trouble is then getting map() to play with the result of dict.values().
I only worked this out while writing this post, of course.
Given a dictionary like d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7,
8, 9]} - I was hoping to do this:
map(None, d.values())
But instead I (finally worked out I could) do this:
apply(map, tuple([None] + d.values()))
So... my bit of code becomes:
filter(None, flatten(map(None, apply(map, tuple([None] +
d.values())))))
It fits on one line, but it feels far more evil than I set out to be.
The brackets at the end are bad for my epilepsy.
Surely there is there some nice builtin function I have missed?
--
| John J. Lehmann, j1o1h1n(@)gmail.com
+ [lost-in-translation] "People using public transport look stern, and
handbag
+ snatchers increase the ill feeling." A Japanese woman, Junko, told
the paper:
+ "For us, Paris is the dream city. The French are all beautiful and
elegant
+ And then, when we arrive..." | |
Share:
| j1*****@gmail.com wrote:
[...]
I had in mind something like this:
>>>interleave([1, 2, 3], [4,5], [7, 8, 9])
[1, 4, 7, 2, 5, 8, 3, 9]
[...]
But instead I (finally worked out I could) do this:
apply(map, tuple([None] + d.values()))
apply is deprecated, it should be map(None, *d.values())
So... my bit of code becomes:
filter(None, flatten(map(None, apply(map, tuple([None] +
d.values())))))
It fits on one line, but it feels far more evil than I set out to be.
The brackets at the end are bad for my epilepsy.
Surely there is there some nice builtin function I have missed?
You have missed the "it doesn't need to be a one-liner" motto :)
>>def interleave(*args):
.... result = []
.... for items in map(None, *args):
.... result.extend([x for x in items if x is not None])
.... return result
....
>>interleave([1, 2, 3], [4,5], [7, 8, 9])
[1, 4, 7, 2, 5, 8, 3, 9]
Cheers,
--
Roberto Bonvallet | | |
On 2006-11-21, j1*****@gmail.com <j1*****@gmail.comwrote:
I had in mind something like this:
>>>interleave([1, 2, 3], [4,5], [7, 8, 9])
[1, 4, 7, 2, 5, 8, 3, 9]
[...] before giving up and going back to trusty old map(), long
celebrated for making code hard to read:
>>>map(None, [1, 2, 3], [4,5], [7, 8, 9])
[(1, 4, 7), (2, 5, 8), (3, None, 9)]
This is basically it. It then becomes:
>>>filter(None, flatten(map(None, [1, 2, 3], [4,5], [7, 8, 9])))
[1, 4, 7, 2, 5, 8, 3, 9]
You can use itertools.chain instead of flatten:
>>from itertools import chain filter(None, chain(*map(None, [1, 2, 3], [4, 5], [7, 8, 9])))
[1, 4, 7, 2, 5, 8, 3, 9]
Trouble is then getting map() to play with the result of dict.values().
I only worked this out while writing this post, of course.
Given a dictionary like d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7,
8, 9]} - I was hoping to do this:
map(None, d.values())
You need the * to "unpack" the list. It has generally taken the
place of apply.
>>map(None, *d.values())
[(1, 7, 4), (2, 8, 5), (3, 9, None)]
So... my bit of code becomes:
>>filter(None, chain(*map(None, *d.values())))
[1, 7, 4, 2, 8, 5, 3, 9]
I don't think that the specific ordering that's achieved has any
valuable significance. You might be just as happy with the
simpler:
>>list(chain(*d.values()))
[1, 2, 3, 7, 8, 9, 4, 5]
--
Neil Cerutti
Weight Watchers will meet at 7 p.m. Please use large double door at the side
entrance. --Church Bulletin Blooper | | |
d = {"a": [1, 2, 3], "b": [4, 5], "c": [7, 8, 9]}
# Simple solution:
result = []
for l in d.itervalues():
result.extend(l)
print result
# Alternative:
from itertools import chain
print list( chain(*d.itervalues()) )
I don't know what's the faster solution, the first one seem more
readable and it's probably fast enough.
Bye,
bearophile | | | j1*****@gmail.com wrote:
filter(None, - my brain parses that automatically now. This is not so
bad. Flatten is snitched from ASPN/Cookbook/Python/Recipe/363051,
thank you Jordan Callicoat, Mike C. Fletcher:
def flatten(l, ltypes=(list, tuple)):
i = 0
while (i < len(l)):
while (isinstance(l[i], ltypes)):
l[i:i+1] = list(l[i])
i += 1
return l
On a side note, that version of flatten doesn't handle an empty list as
the last element of a list...
>>flatten([1, 2, 3, []])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in flatten
IndexError: list index out of range
You need a try: in there or something...
def flatten(l, ltypes=(list, tuple)):
i = 0
while(i < len(l)):
try:
while(isinstance(l[i], ltypes)):
l[i:i+1] = list(l[i])
i += 1
except IndexError:
pass
return l
noah | | | j1*****@gmail.com wrote:
Hello,
I was trying to create a flattened list of dictionary values where each
value is a list, and I was hoping to do this in some neat functionally
style, in some brief, throwaway line so that it would assume the
insignificance that it deserves in the grand scheme of my program.
I had in mind something like this:
>>>>interleave([1, 2, 3], [4,5], [7, 8, 9])
[1, 4, 7, 2, 5, 8, 3, 9]
I played for a while with zip(), [some newfangled python keyword, that
I was truly shocked to find has been hiding at the bottom of the list
built in functions since version 2.0], before giving up and going back
to trusty old map(), long celebrated for making code hard to read:
>>>>map(None, [1, 2, 3], [4,5], [7, 8, 9])
[(1, 4, 7), (2, 5, 8), (3, None, 9)]
This is basically it. It then becomes:
>>>>filter(None, flatten(map(None, [1, 2, 3], [4,5], [7, 8, 9])))
[1, 4, 7, 2, 5, 8, 3, 9]
filter(None, - my brain parses that automatically now. This is not so
bad. Flatten is snitched from ASPN/Cookbook/Python/Recipe/363051,
thank you Jordan Callicoat, Mike C. Fletcher:
def flatten(l, ltypes=(list, tuple)):
i = 0
while (i < len(l)):
while (isinstance(l[i], ltypes)):
l[i:i+1] = list(l[i])
i += 1
return l
Trouble is then getting map() to play with the result of dict.values().
I only worked this out while writing this post, of course.
Given a dictionary like d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7,
8, 9]} - I was hoping to do this:
map(None, d.values())
But instead I (finally worked out I could) do this:
apply(map, tuple([None] + d.values()))
So... my bit of code becomes:
filter(None, flatten(map(None, apply(map, tuple([None] +
d.values())))))
It fits on one line, but it feels far more evil than I set out to be.
The brackets at the end are bad for my epilepsy.
Surely there is there some nice builtin function I have missed?
--
| John J. Lehmann, j1o1h1n(@)gmail.com
+ [lost-in-translation] "People using public transport look stern, and
handbag
+ snatchers increase the ill feeling." A Japanese woman, Junko, told
the paper:
+ "For us, Paris is the dream city. The French are all beautiful and
elegant
+ And then, when we arrive..."
What about :
>>d = { "a" : [1, 2, 3], "b" : [4, 5], "c" : [7, 8, 9]} L=[] for x in d.values(): L.extend(x)
....
>>L
[1, 2, 3, 7, 8, 9, 4, 5]
or a little curious:
>>L=[] map(L.extend, d.values())
[None, None, None]
>>L
[1, 2, 3, 7, 8, 9, 4, 5]
TV | | This discussion thread is closed Replies have been disabled for this discussion. Similar topics
4 posts
views
Thread by brianobush@gmail.com |
last post: by
|
125 posts
views
Thread by Raymond Hettinger |
last post: by
|
2 posts
views
Thread by jg |
last post: by
|
1 post
views
Thread by john wright |
last post: by
|
5 posts
views
Thread by Andrew Robinson |
last post: by
|
14 posts
views
Thread by vatamane@gmail.com |
last post: by
|
3 posts
views
Thread by Rich Shepard |
last post: by
|
4 posts
views
Thread by O.B. |
last post: by
|
20 posts
views
Thread by Gustaf |
last post: by
| | | | | | | | | | |