简体   繁体   中英

Converting a list or string into a dictionary and returning only specific keys/values from that dictionary

I've been working on a function that can convert a list/string into a dictionary and I'm able to run it on a bunch of different samples successfully. For instance, I took a list of the letters in the alphabet (az) and assigned them a number (1-26):

import string
mylist = list(string.ascii_lowercase)

def list_conversion(items):
    print(dict(enumerate(items, 1)))

so when I call list_conversion(mylist) I get the output that I'm looking for:

{1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z'}

However, I'm not sure how to run this function and only return specific keys/values. For instance, I want to return on the values for odd number keys. I understand how to do this in an isolated instance:

d = {'x': 1, 'y': 2, 'z': 3} 
for key, value in d.items():
    if value%2 != 0:
        print(key)

But I can't figure out how to build this into my function correctly. How would I build such a for loop into my function that returns only even/odd values and more broadly, how can I return only specific keys/values that I choose from this function? I thought that something like this would work:

def list_conversion(items):
    print(dict(enumerate(items, 1)))

list_conversion(mylist)

for key, value in mylist.items():
    if value%2 != 0:
        print(key)

However, I get AttributeError: 'list' object has no attribute 'items' so I get the sense I'm going down the wrong path here.

To answer the more broad question, you need to provide some mechanism by which you can determine whether or not the key is allowable for your result. I would modify your function like so:

>>> import string
>>> 
>>> def list_conversion(alist, filterfunc = None):
...   # Handle the case where you just want all values
...   if filterfunc is None:
...     return dict(enumerate(alist, 1))
...   # Handle other cases where filterfunc is a callable
...   return {k: v for k, v in enumerate(alist, 1) if filterfunc(k)}
... 
>>> list_conversion(string.ascii_lowercase, lambda x: x % 2) # odds
{1: 'a', 3: 'c', 5: 'e', 7: 'g', 9: 'i', 11: 'k', 13: 'm', 15: 'o', 17: 'q', 19: 's', 21: 'u', 23: 'w', 25: 'y'}
>>> list_conversion(string.ascii_lowercase, lambda x: not x % 2) # evens
{2: 'b', 4: 'd', 6: 'f', 8: 'h', 10: 'j', 12: 'l', 14: 'n', 16: 'p', 18: 'r', 20: 't', 22: 'v', 24: 'x', 26: 'z'}

You can pass a more specific function in as well:

>>> def arbitrary(key):
...   wanted = [1,5,12,13,15]
...   return key in wanted
... 
>>> list_conversion(string.ascii_lowercase, arbitrary)
{1: 'a', 15: 'o', 12: 'l', 5: 'e', 13: 'm'}

You better take the print out of the function.

def list_conversion(items):
    return {i: x for i, x in enumerate(items, 1) if i % 2 == 1}

Various changes to your code. list_conversion should return a dictionary. No need to convert string.ascii_lowercase to a list, as enumerate will iterate over the elements of the string. Finally, I use a list comprehension for efficiency rather than a loop.

import string

def list_conversion(items):
    return dict(enumerate(items, 1))

mylist = list_conversion(string.ascii_lowercase)
[k for k, v in mylist.items() if k%2 != 0]

# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM