简体   繁体   中英

List comprehension vs dictionary comprehension

Good evening people,

I have the following code that modifies dictionary values 'in place'

translate1 = {k:(0 if v > 300 and v < 900 else v) for k, v in translate1.items()}
translate1 = {k:(1 if v > 1400 and v < 2100 else v) for k, v in translate1.items()}
translate1 = {k:(2 if v > 8700 and v < 9100 else v) for k, v in translate1.items()}
translate1 = {k:(3 if v > 3800 and v < 4100 else v) for k, v in translate1.items()}
translate1 = {k:(4 if v > 6400 and v < 7000 else v) for k, v in translate1.items()}

My question is, can a similar objective be achieved with list comprehension? I want all of the values to be in order in the same list.

Thanks in advance

List comps is no cure-all, what you need is a lookup to reduce iterating all items() 5 times down to 1 time:

def mapper(v):
    if 300 < v < 900:   # syntactical equivalent to v > 300 and v < 900
        return 0
    if 1400 < v < 2100:
        return 1
    if 8700 < v < 9100:
        return 2
    if 3800 < v < 4100:
        return 3
    if 6400 < v < 7000:
        return 4
    return v


translate1 = {k:mapper(v) for k, v in translate1.items()} 

You are missing some values - I hope thats intentional.

I would write your function like so:

def mapper(v):
    di={
        (300,900):      0,
        (1400,2100):    1,
        (8700,9100):    2,
        (3800,4100):    3,
        (6400,7000):    4
    }
    for (t0,t1),ret in di.items():
        if t0<v<t1: return ret 
    return v

translate1={k:mapper(v) for k,v in translate1.items()}

That is not materially different than Patrick Artner's answer other than the form of the mapper function as a dict of tuples.

Couple of other comments:

  1. The form di={k:f(v) for k,v in di.items()} is not doing in place updates on di . Instead the dict comprehension is first creating a new anonymous dict and then assigns that dict to the name di when it is done. The main issue (perhaps) is that the memory requirements for doing that are at least 2x more than in place assignment.
  2. The only form of 'in-place' update with a comprehension is either:
    1. Use a slice assignment li[:]=[list comprehension] or
    2. Use .update with a dict comprehension di.update({dict comprehension on a subset of di})
  3. There is no advantage to using a list comprehension in preference to a dict comprehension to create a dict.
  4. Dict's only have any 'order' on Python 3.6+. They use insertion order in this case.

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