我在Python中有两种算法,可以将元组列表转换成字典:
def _prep_high_low_data_for_view(self, low_high_list):
dates = []
prices = []
lables = []
for (x, y, z) in low_high_list:
dates.append(x)
prices.append(y)
lables.append(z)
return {'date': dates,
'price': prices,
'label': lables
}
第二个是:
def _prep_high_low_data_for_view(self, low_high_list):
return {'date': [date for date, _, _ in low_high_list],
'price': [price for _, price, _ in low_high_list],
'label': [lable for _, _, lable in low_high_list],
}
这两种算法在功能上是等效的。 是否存在第二种算法,因为存在三个单独的列表理解,因此第二种算法在复杂性方面更差吗?
答案 0 :(得分:4)
您可以使用zip构建3个列表:
dates,prices,labels = zip(*low_high_list)
放在一行函数中:
def third_function(low_high_list):
return dict.fromkeys(zip(["date","price","label"],zip(*low_high_list)))
平均而言,它比Florian_H中的second_function()运行得更快。
测试和结果:
def third_function(low_high_list):
return dict.fromkeys(zip(["date","price","label"],zip(*low_high_list)))
def fourth_function(low_high_list):
dates,prices,labels = zip(*low_high_list)
return { "date":dates, "price":prices, "label":labels }
lst = [tuple(random.randint(0,100) for _ in range(3)) for i in range(10000)]
from timeit import timeit
count = 1000
t0 = timeit(lambda:first_function(lst), number=count)
print("first_function: ",f"{t0:.3f}","1x" )
t = timeit(lambda:second_function(lst), number=count)
print("second_function:",f"{t:.3f}",f"{t0/t:.1f}x" )
t = timeit(lambda:third_function(lst), number=count)
print("third_function: ",f"{t:.3f}",f"{t0/t:.1f}x" )
t = timeit(lambda:fourth_function(lst), number=count)
print("fourth_function:",f"{t:.3f}",f"{t0/t:.1f}x" )
# first_function: 1.338 1x
# second_function: 0.818 1.6x
# third_function: 0.426 3.1x
# fourth_function: 0.375 3.6x
答案 1 :(得分:3)
是,不是。
它基本上是O(n)
与O(3n)
的比较,但是当处理复杂性时,O(3n)
会缩短为O(n)
。
是的,这两种算法都具有O(n)
的复杂性,但是第一个算法的运算量要少三倍。
答案 2 :(得分:1)
正如Markust Meskanen提到的那样,第一个算法应该快3倍(不太复杂),但是为什么不尝试一下呢?在这里,您的代码具有随机值和时间度量。
import random, datetime
def first_function(low_high_list):
dates = []
prices = []
lables = []
for (x, y, z) in low_high_list:
dates.append(x)
prices.append(y)
lables.append(z)
return {'date': dates,
'price': prices,
'label': lables
}
def second_function(low_high_list):
return {'date': [date[0] for date in low_high_list],
'price': [price[1] for price in low_high_list],
'label': [label[2] for label in low_high_list],
}
def second_function(low_high_list):
return {'date': [date[0] for date in low_high_list],
'price': [price[1] for price in low_high_list],
'label': [label[2] for label in low_high_list],
}
lst = [[random.randint(0,100),random.randint(0,100),random.randint(0,100)] for i in range(10000)]
print("first_function:")
tmp = datetime.datetime.now()
first_function(lst)
print(datetime.datetime.now() - tmp)
print("\nsecond_function:")
tmp = datetime.datetime.now()
second_function(lst)
print(datetime.datetime.now() - tmp)
瞧,第二个功能比第一个功能快两倍...
[output]
first_function:
0:00:00.004001
second_function:
0:00:00.002001
看起来,即使第二个函数运行了三次而不是一次,在这种情况下,列表理解仍然是循环附加列表的两倍。
1000倍的平均速度仍然大约是其两倍:
0:00:00.002820
0:00:00.001568