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 for
s , 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()
this graph plots relative time difference compared solution. note x-axis (the sizes) logarithmic while y-axis (time difference) isn't.
Comments
Post a Comment