2

I have a dictionary which looks like

a = {32: [2230], 37265: [2218], 51: [2223], 164: [2227], 3944: [2224]}

however, values in a could contain multiple elements, like

a = {32: [2200, 2230], 37265: [2201, 2218], 51: [2223], 164: [2227], 3944: [2224]}

I have a list that stores the keys in a in groups,

b = [[32, 51, 164], [3944, 37265]]

now I want to get values of keys in each group in another list,

        clusters = []
        for key_group in b:
            group = []

            for key in key_group:
                group.extend(a[key])

            if len(group) > 1:
                clusters.append(group) 

so the final list looks like,

clusters = [[2230, 2223, 2227], [2224, 2218]]

if a contains multiple elements in a value list, clusters looks like,

clusters = [[2200, 2230, 2223, 2227], [2224, 2201, 2218]]

I am wondering what's the best way to do this.

Also in case when b contains list(s) which has only one value/key, and if this key maps to a single element list in a, this list will be ignored,

a = {32: [2200, 2230], 37265: [2201, 2218], 51: [2223], 164: [2227], 3944: [2224]}

b = [[32, 51, 164], [3944], [37265]]

while 3944 maps to [2224], which will be ignored, but 37265 maps to [2201, 2218], which will be kept, since len([2201, 2218]) > 1. clusters will look like the following in this case,

clusters = [[2200, 2230, 2223, 2227], [2201, 2218]]         
5
  • 1
    Can you clarify what you mean by "best"? Commented Nov 9, 2017 at 15:31
  • @PeterWood concise, simpler, more efficient way? Commented Nov 9, 2017 at 15:32
  • I edited the answer let me know if that works for you :) Commented Nov 9, 2017 at 15:44
  • @DamianLattenero the top 3 answers all work :) Commented Nov 9, 2017 at 15:45
  • @daiyue great! I have to practice to give better answer haha... Commented Nov 9, 2017 at 15:48

4 Answers 4

5

Assuming your values in a are always just a list with a single element, then it is a simple nested list comprehension:

[[a[k][0] for k in sublist] for sublist in b]
# [[2230, 2223, 2227], [2224, 2218]]

Since you've now clarified the values of a can be lists with multiple elements, you can use itertools.chain.from_iterable to flatten the lists returned and give your desired output:

from itertools import chain
[list(chain.from_iterable(a[k] for k in sublist)) for sublist in b]
# [[2200, 2230, 2223, 2227], [2224, 2201, 2218]]
Sign up to request clarification or add additional context in comments.

7 Comments

thx for your reply, but values in a could contain multiple elements.
@daiyue can you show the desired output for your a with multiple elements
@Chris_Rands see my op
@Chris_Rands but the answer should also account for if len(group) > 1: as in the code of my op
@daiyue sorry I don't understand, you'll need to add another example that illustrates the behaviour you want
|
4

You can use list comp to do the same job:

clusters = [[a[key][0] for key in k] for k in b]

res => [[2230, 2223, 2227], [2224, 2218]]

if a could have multiple elems, you can do also:

clusters = [[it for key in k for it in a[key]] for k in b]

res => [[2200, 2230, 2223, 2227], [2224, 2201, 2218]]

Comments

2

I would suggest using a triple list comprehension:

list(filter(lambda l:len(l) > 1, ([elem for key in lst for elem in a[key]] for lst in b)))

This works for list values of arbitrary length. filter removes the lists with one or zero elements.

Comments

2

According to your edit:

[[item for i in sub for item in a[i]] for sub in b]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.