简体   繁体   中英

Using List Comprehension with Dictionaries in Python

I'm trying to get my head around list comprehensions and I can understand the basics of how they work but I get the feeling I should be able to do something with my code here that I just can't seem to get working.

Given a dictionary:

{2: {11},  9: {11, 8, 10}, 10: {11, 3}, 11: {7, 5},  8: {7, 3}}

There are a couple of snippets that I feel I should be able to reduce to fewer lines if I knew better:

for k, v in d.items():
    dag[k] = v
    for val in v:
        if val not in d.keys():
            dag[val] = None

and:

t = []
for k, v in d.items():
    if not v:
        t.append(k)
        d.pop(k)

My attempts have been variations on:

for [k, v in d.items() if not v]:

But that keeps telling me it needs an else statement and none of what I have read has helped answer how/if this is possible.

If you want to keep the keys that have falsey values the syntax is:

[ k for k, v in d.items() if not v]

That is equivalent to your last loop bar the d.pop(k) which I am not sure if you want. The first k is what we append to the list, for k, v is each key and value in d.items and if not v means we only keep the k's that have falsey values.

If you actually want a dict without those keys and value you can use a dict comprehension where the logic is exactly the same except we are creating key/value pairings instead of just keeping just the keys in the list comprehension:

{ k:v for k, v in d.items() if not v}

As for your first code, I am not sure what you want it to do exactly but you should not be calling .keys , in python2 that creates a list and makes lookups O(n) as opposed to 0(1) and in python 3 it is an unnecessary function call.

In your first snippet, you are essentially defaulting all nodes to None in the dag . You could invert those steps and avoid testing for keys already being present altogether:

dag = dict.fromkeys(node for v in d.values() for node in v)
dag.update(d)

This creates a dictionary with all None values for the given keys (sourced from a generator expression), then updated to insert all known edges.

In your code you used if val not in d.keys() ; this is functionally equivalent to if val not in d , but without the redundant call to d.keys() , which creates a new object (in Python 2, a list with all keys, making the search extra inefficient, in Python 3 a dictionary view is created). Always use the shorter form there.

Do be aware that the set objects you use as values in d are now shared with dag ; any changes you make to these sets will be reflected across both dictionaries.

Creating a sequence of nodes without values would then be:

nodes_without_exits = [node for node, edges in d.items() if not node]

List comprehensions still need the producer expression , the part that produces the value to be inserted into the list; here that's node , the list is built out of the keys of the dictionary.

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