None in string => TypeError?

Chris Angelico rosuav at gmail.com
Mon Jun 9 13:40:32 EDT 2014


On Tue, Jun 10, 2014 at 3:22 AM, Ian Kelly <ian.g.kelly at gmail.com> wrote:
> On Mon, Jun 9, 2014 at 10:59 AM, Chris Angelico <rosuav at gmail.com> wrote:
>> On Tue, Jun 10, 2014 at 2:53 AM, Roy Smith <roy at panix.com> wrote:
>>> In retrospect, I suspect:
>>>
>>>           hourly_data = [(t if status in set('CSRP') else None) for (t,
>>> status) in hours]
>>>
>>> is a little cleaner.
>>
>> I'd go with this. It's clearer that a status of 'SR' should result in
>> False, not True. (Presumably that can never happen, but it's easier to
>> read.) I'd be inclined to use set literal syntax, even though it's a
>> bit longer - again to make it clear that these are four separate
>> strings that you're checking against.
>
> Depending on how much work this has to do, I might also consider
> moving the set construction outside the list comprehension since it
> doesn't need to be repeated on every iteration.

Set literal notation will accomplish that, too, for what it's worth.

>>> def x():
hourly_data = [(t if status in {'C','S','R','P'} else None) for (t,
status) in hours]

>>> dis.dis(x)
  2           0 LOAD_CONST               1 (<code object <listcomp> at
0x012BE660, file "<pyshell#10>", line 2>)
              3 LOAD_CONST               2 ('x.<locals>.<listcomp>')
              6 MAKE_FUNCTION            0
              9 LOAD_GLOBAL              0 (hours)
             12 GET_ITER
             13 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             16 STORE_FAST               0 (hourly_data)
             19 LOAD_CONST               0 (None)
             22 RETURN_VALUE
>>> dis.dis(x.__code__.co_consts[1])
  2           0 BUILD_LIST               0
              3 LOAD_FAST                0 (.0)
        >>    6 FOR_ITER                36 (to 45)
              9 UNPACK_SEQUENCE          2
             12 STORE_FAST               1 (t)
             15 STORE_FAST               2 (status)
             18 LOAD_FAST                2 (status)
             21 LOAD_CONST               5 (frozenset({'R', 'S', 'C', 'P'}))
             24 COMPARE_OP               6 (in)
             27 POP_JUMP_IF_FALSE       36
             30 LOAD_FAST                1 (t)
             33 JUMP_FORWARD             3 (to 39)
        >>   36 LOAD_CONST               4 (None)
        >>   39 LIST_APPEND              2
             42 JUMP_ABSOLUTE            6
        >>   45 RETURN_VALUE
>>> isinstance(x.__code__.co_consts[1].co_consts[5],set)
False

Interestingly, the literal appears to be a frozenset rather than a
regular set. The compiler must have figured out that it can never be
changed, and optimized.

Also, this is the first time I've seen None as a constant other than
the first. Usually co_consts[0] is None, but this time co_consts[4] is
None.

ChrisA



More information about the Python-list mailing list