1

I have a dictionary of arrays.

mydict={'a':[45,65,78,32], 'b':['red','blue','green','yellow'], 'c':[3.4, 4.5, 6.5, 7.6]}

I want to pull the elements of mydict['b'] when mydict['a'] is greater than 35. I want

myarr = ['red','blue','green']

I tried -

myarr = [mydict['b'] for num in mydict['a'] num > 35]

I do not want to go the C++/C route of enumerating and saving the index and using the index. Not Sounds like Python.

How do I do this?

Mehrdad Pedramfar
  • 10,941
  • 4
  • 38
  • 59

5 Answers5

3

you're close, you need to use zip:

[b for a, b in zip(mydict['a'], mydict['b']) if a > 35]
acushner
  • 9,595
  • 1
  • 34
  • 34
3

Create a new list if the val of dict['a'] > 35:

mydict = {'a':[45,65,78,32], 'b':['red','blue','green','yellow'], 'c':[3.4, 4.5, 6.5, 7.6]}

Python 3.x:

Using itertools.zip_longest(*iterables, fillvalue=None):

From the docs:

Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted

print([y for x,y in zip_longest(mydict['a'],mydict['b']) if x > 35])

Python 2.x:

Using itertools.izip_longest(*iterables[, fillvalue])

print([y for x,y in izip_longest(mydict['a'],mydict['b']) if x > 35])

OUTPUT:

['red', 'blue', 'green']

EDIT:

What is the difference between zip() and zip_longest()?

Consider the following lists:

x = [1,2,3,4,5]    
y = ['a','b','c']

for a,b in zip(x,y):
    print(a,b)

OUTPUT:

1 a
2 b
3 c

It clearly skipped the elements 4,5 in the x since it could not find its correspondings in the y.

Using zip_longest():

x = [1,2,3,4,5]    
y = ['a','b','c']

for a,b in zip_longest(x,y):
    print(a,b)

OUTPUT:

1 a
2 b
3 c
4 None
5 None

It did not skip the elements in the x, instead filled the missing ones in the y with a None.

DirtyBit
  • 16,613
  • 4
  • 34
  • 55
1

You can use enumerate to access the corresponding index i using which you can get the corresponding value from mydict['b'].

myarr = [mydict['b'][i]  for i, num in enumerate(mydict['a']) if num > 35]
# ['red', 'blue', 'green']
Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • 2
    *I do not want to go the C++/C route of enumerating and saving the index and using the index.* – pault Apr 17 '19 at 14:08
1

Try this:

[j for i,j in zip(mydict['a'],mydict['b']) if i>35] 
Mehrdad Pedramfar
  • 10,941
  • 4
  • 38
  • 59
1

If you're open to using pandas, this type of filtering is quite easy.

First pass mydict to the DataFrame constructor:

import pandas as pd
df = pd.DataFrame(mydict)
print(df)
#    a       b    c
#0  45     red  3.4
#1  65    blue  4.5
#2  78   green  6.5
#3  32  yellow  7.6

Now use a boolean mask to filter the columns that meet your condition:

print(df[df['a']>35])
#    a      b    c
#0  45    red  3.4
#1  65   blue  4.5
#2  78  green  6.5

To get your desired output as a list, you can do:

myarr = df[df['a']>35]['b'].values.tolist()
print(myarr)
#['red', 'blue', 'green']
pault
  • 41,343
  • 15
  • 107
  • 149