the PHP ternary operator equivalent on Python
Steven D'Aprano
steve at REMOVEMEcyber.com.au
Thu Nov 24 03:12:33 EST 2005
rurpy at yahoo.com wrote:
> Fredrik Lundh wrote:
>
>>def convert(old):
>>
>> new = dict(
>> CODE=old['CODEDATA'],
>> DATE=old['DATE']
>> )
>>
>> if old['CONTACTTYPE'] == 2:
>> new['CONTACT'] = old['FIRSTCONTACT']
>> else:
>> new['CONTACT'] = old['SECONDCONTACT']
>>
>> return new
>
>
> I don't find your code any more readable than the OP's
> equivalent code:
>
> def convert(old):
> new = {
> CODE: old['CODEDATA'],
> DATE: old['DATE'],
> CONTACT: old['FIRSTCONTACT'] \
> if old['CONTACTTYPE'] == 2 \
> else old['OLDDCONTACT']
> }
> return new
The problem I have with your code is that it is too
similar to:
def convert(old):
new = {
CODE: old['CODEDATA'],
DATE: old['DATE'],
CONTACT: old['FIRSTCONTACT'] }
if old['CONTACTTYPE'] == 2:
else: old['OLDDCONTACT']
return new
Yes, the above code is broken. But it *looks* right, at
first glance, unless you train yourself to never write
if cond: TRUE_CLAUSE
else: FALSE_CLAUSE
as a two-liner.
Regardless of whatever benefits the ternary operator is
going to have, in my opinion allowing people to write
TRUE_CLAUSE if COND else FALSE_CLAUSE will increase the
amount of poorly written, hard to read code.
> The OPs code make one pass through the dict, your's makes
> two.
The original code binds a name to an empty dict, then
rebinds the name to a populated dict.
Your code simply creates the dict in one step.
Fredrik's code creates an initial dict, then adds a new
key and value to it. That's hardly making two passes
through the dict -- what does that even mean?
> I do not know what effect (if any) that has in the case of
> a very large dict.
Quick and dirty speed test:
py> from time import time
py> def makedict1():
... return dict.fromkeys(range(1000))
...
py> def makedict2():
... D = {}
... for i in range(1000):
... D[i]=None
... return D
...
py> assert makedict1() == makedict2()
py> def test(func, n=100):
... t = time()
... for i in range(n):
... tmp = func()
... return (time() - t)/n
...
py> test(makedict1)
0.00020779848098754884
py> test(makedict2)
0.00042409896850585936
That's not timing quite the same thing you refer to,
but it is suggestive: if you create an empty dict, and
then populate it one item at a time, it will take
approximately twice as long as creating the non-empty
dict directly.
As a very unscientific, system-dependent, statistically
shoddy ball-park estimate, it looks like each item
assignment to a pre-existing dict takes less than
0.0000002s. So if you had a dict and added another
million items to it, one at a time, it might take an
extra 0.2s in total more than what it would have taken
you if you wrote those one million items in your source
code.
I can live with that.
--
Steven.
More information about the Python-list
mailing list