2

This is the list in Python:

a = [{a:3,b:4}, {c:14,d:24}]

How can I create a list consisting only from the values of the dictionaries?

Like this:

a1=[3,4,14,24]

I have made this with a for loop, but is there an other way of doing this?

Oren
  • 4,152
  • 3
  • 30
  • 37
user2013804
  • 29
  • 1
  • 4
  • 2
    How do you want the final results ordered? From your example, it's hard to tell whether you want them in sorted order of the values, in sorted order of the keys, in arbitrary order within a given dict but in the order of the dicts, etc. – DSM Jan 26 '13 at 15:37
  • The language is Python, and the order doesn't matter. I need only the values of the dictionaries, not their keys. – user2013804 Jan 26 '13 at 15:42

4 Answers4

3

Since the order apparently doesn't matter:

>>> a = [{'a':3,'b':4}, {'c':14,'d':24}]
>>> a
[{'a': 3, 'b': 4}, {'c': 14, 'd': 24}]

You can get the values in a listcomp:

>>> [d.values() for d in a]
[[3, 4], [14, 24]]

And then flatten this using a nested listcomp:

>>> [value for d in a for value in d.values()]
[3, 4, 14, 24]

which is equivalent to

>>> newlist = []
>>> for d in a:
...     for value in d.values():
...         newlist.append(value)
... 
>>> newlist
[3, 4, 14, 24]

If you really don't even want the word for in there, I guess you could use

>>> from itertools import chain
>>> list(chain(*map(dict.values, a)))
[3, 4, 14, 24]

[Update:]

Some performance comparisons (mostly for information's sake about the scaling at large N):

>>> a = [{'a':3,'b':4}, {'c':14,'d':24}]
>>> 
>>> timeit [value for d in a for value in d.itervalues()]
1000000 loops, best of 3: 1.02 us per loop
>>> timeit [value for d in a for value in d.values()]
1000000 loops, best of 3: 1.32 us per loop
>>> timeit list(chain(*map(dict.values, a)))
100000 loops, best of 3: 4.45 us per loop
>>> timeit reduce(operator.add, (d.values() for d in a))
100000 loops, best of 3: 2.01 us per loop
>>> timeit sum((d.values() for d in a), [])
100000 loops, best of 3: 2.08 us per loop
>>> 
>>> a = [{'a':3,'b':4}, {'c':14,'d':24}] * 1000
>>> 
>>> timeit [value for d in a for value in d.itervalues()]
1000 loops, best of 3: 612 us per loop
>>> timeit [value for d in a for value in d.values()]
1000 loops, best of 3: 915 us per loop
>>> timeit list(chain(*map(dict.values, a)))
1000 loops, best of 3: 1.07 ms per loop
>>> timeit reduce(operator.add, (d.values() for d in a))
100 loops, best of 3: 17.1 ms per loop
>>> timeit sum((d.values() for d in a), [])
100 loops, best of 3: 17.1 ms per loop
DSM
  • 342,061
  • 65
  • 592
  • 494
  • `sum((d.values() for d in a), [])` – Ismail Badawi Jan 26 '13 at 15:46
  • @isbadawi: using `sum` that way will have very poor performance when there are lots of dictionaries. – DSM Jan 26 '13 at 15:50
  • list(chain(*map(dict.values, a))) what this actually does? I mean for what we use map? – user2013804 Jan 26 '13 at 16:05
  • @user2013804: `map(func, seq)` (in Python 2) applies the function to the sequence and produces a list. The function is the `.values` method of a `dict`, so `map(dict.values, a) == [[3, 4], [14, 24]]`. The `*` turns a list into function arguments, so `chain(*[[3,4], [14,24]])` is like `chain([3,4], [14,24])`, `chain` is an object which joins things, and `list` turns it into a list. – DSM Jan 26 '13 at 16:09
  • try: `chain.from_iterable(imap(methodcaller('values'), a))` to support dict-like objects and large `len(a)`. See [Flattening a shallow list in Python](http://stackoverflow.com/questions/406121/flattening-a-shallow-list-in-python) – jfs Jan 26 '13 at 17:38
2

This can be done in asingle line using list comprehensions :

>>> a = [{'a':3,'b':4}, {'c':14,'d':24}]    #List


>>> [v for d in a for v in d.values()] #Comprehension
    [3, 4, 14, 24]
asheeshr
  • 4,088
  • 6
  • 31
  • 50
1
In [9]: import operator

In [10]: a = [{'a':3,'b':4}, {'c':14,'d':24}]

In [11]: reduce(operator.add, (d.values() for d in a))
Out[11]: [3, 4, 14, 24]

Bear in mind that Python dictionaries are unordered. This means that the ordering of keys (and their values) within each of the dictionaries is not guaranteed.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

Using itertools chain method:

import itertools

a = [{'a':3,'b':4}, {'c':14,'d':24}]
list(itertools.chain(*(x.itervalues() for x in a)))
>>> [3, 4, 14, 24]
zenpoy
  • 19,490
  • 9
  • 60
  • 87