python - How to conditionally put multiple elements at a time in list comprehension? -


i have discovered close question:

adding 2 items @ time in list comprehension

but if need switch between single or double, like:

original = list(range(10)) required = [0,0,1,2,2,3,4,4,5,6,6,7,8,8,9] attempt1 = sum([[x,x] if x%2 == 0 else [x] x in original],[]) attempt2 = [i x in original in ([x,x] if x%2 == 0 else [x])] 

sum seems slow, , list comprehension hard read. neither of them makes me feel simple , good.

is there better way it? or abandon one-line way? or convince me if 1 of them style.

personally use generator function have more non-trivial stuff going on in comprehension (for example 2 fors , 1 if).

for example in case use (i think it's more readable might subjective):

def double_evens(inp):     item in inp:         if item % 2 == 0:             yield item         yield item 

test run:

>>> list(double_evens(range(10))) [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9] 

note approach faster (it's 3 times faster other solutions in answers , 2 times faster comprehension on computer). taking timing framework this answer:

from itertools import chain  def coldspeed1(mylist):     return [y x in mylist y in [x] * (2 - x % 2)]  def coldspeed2(mylist):     return list(chain.from_iterable([x] * (2 - x % 2) x in mylist))  def double_evens(inp):     item in inp:         if not item % 2:             yield item         yield item  def mseifert(inp):     return list(double_evens(inp))    def ettanany(my_list):     new_list = [[i] * 2 if % 2 == 0 else in my_list]     res = []     in new_list:         if isinstance(i, list):             res.extend(i)         else:             res.append(i)     return res  def no1xsyzy(original):     return [i x in original in ([x,x] if x%2 == 0 else [x])]  # timing setup timings = {coldspeed1: [], coldspeed2: [], mseifert: [], ettanany: [], no1xsyzy: []} sizes = [2**i in range(1, 20, 2)]  # timing size in sizes:     mylist = list(range(size))     func in timings:         res = %timeit -o func(mylist)         timings[func].append(res)  # plotting %matplotlib notebook  import matplotlib.pyplot plt import numpy np  fig = plt.figure(1) ax = plt.subplot(111)  baseline = mseifert # choose 1 function baseline func in timings:     ax.plot(sizes,              [time.best / ref.best time, ref in zip(timings[func], timings[baseline])],              label=str(func.__name__)) #ax.set_yscale('log') ax.set_xscale('log') ax.set_xlabel('size') ax.set_ylabel('time relative {}'.format(baseline.__name__)) ax.grid(which='both') ax.legend() plt.tight_layout() 

enter image description here

this graph plots relative time difference compared solution. note x-axis (the sizes) logarithmic while y-axis (time difference) isn't.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -