pepero
pepero

Reputation: 7513

combine lists in list/dict comprehension way

is it possible to apply list/dictionary comprehension to the following code to have ["abc", "ab", "cd"]

tk = {}
tk[1] = ["abc"]
tk[2] = ["ab", "cd"]
tk[3] = ["ef", "gh"]
t = (1, 2)
combined = []
combined.append(tk[i]) for i in t #does not work. note, not all tk values are used, this is based on t.

I could think of ll = [tk[i] for i in t], then this turns to be flatten list out of lists. so

ll = [tk[i] for i in t]
[item for sublist in ll for item in sublist]

but this is not one-liner. I wonder if there is better way.

Upvotes: 0

Views: 1393

Answers (3)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96287

Given your constraint of choosing a sequence of keys manually:

>>> tk = {}
>>> tk[1] = ["abc"]
>>> tk[2] = ["ab", "cd"]
>>> tk[3] = ["ef", "gh"]

You want:

>>> [vals for i in (1,2) for vals in tk[i]]
['abc', 'ab', 'cd']

Upvotes: 1

Matheus Portela
Matheus Portela

Reputation: 2470

Simply iterate through the values of your dictionary. Something like this:

>>> tk = {}
>>> tk[1] = ['abc']
>>> tk[2] = ['ab', 'cd']
>>> combined = [x for t in tk.values() for x in t]
>>> print combined
['abc', 'ab', 'cd']

You can even use an OrderedDict if you need to maintain the order of your lists, since a regular dict does not guarantee the order of its keys:

>>> import collections
>>> tk = collections.OrderedDict()
>>> tk[1] = ['abc']
>>> tk[2] = ['ab', 'cd']
>>> combined = [x for t in tk.values() for x in t]
>>> print combined
['abc', 'ab', 'cd']

Note that [tk[i] for i in (1, 2)], as you proposed, won't have the desired results. You still need to iterate through the values inside each list.

>>> [tk[i] for i in (1, 2)]
[['abc'], ['ab', 'cd']]

Also note that [tk[i] for i in tk], as you proposed later, is exactly the same as tk.values(). So you could the proposed solution [x for t in tk.values() for x in t] is equivalent to what you achieved but in one line.

Upvotes: 2

Moinuddin Quadri
Moinuddin Quadri

Reputation: 48120

If the order of values in the desired list matters, the generalized way to achieve this would be to sort the items in the dict based on the key, and merge the list of values. For example:

>>> from operator import itemgetter
>>> from itertools import chain

>>> list(chain.from_iterable(i for _, i in sorted(tk.items(), key=itemgetter(0))))
['abc', 'ab', 'cd']

Upvotes: 2

Related Questions