我想询问是否/如何重写下面这些行,以便更快地运行。
*( - 10000,10000)只是我可以确定我的数字介于两者之间的范围。
first = 10000
last = -10000
for key in my_data.keys():
if "LastFirst_" in key: # In my_data there are many more keys with lots of vals.
first = min(first, min(my_data[key]))
last = max(last, max(my_data[key]))
print first, last
此外,是否有任何pythonic方式来写(即使这并不意味着它会运行得更快)?
THX
答案 0 :(得分:2)
使用>>> my_data = {'LastFirst_1':[1, 4, 5], 'LastFirst_2':[2, 4, 6]}
>>> d = [item for k,v in my_data.items() if 'LastFirst_' in k for item in v]
>>> first = 2
>>> last = 5
>>> min(first, *d)
1
>>> max(last, *d)
6
运算符解压缩值:
myClass()
答案 1 :(得分:0)
values = [my_data[k] for k in my_data if 'LastKey_' in k]
flattened = [item for sublist in values for item in sublist]
min(first, min(flattened))
max(last, max(flattened))
或
values = [item for sublist in (j for a, j in d.iteritems() if 'LastKey_' in a) for item in sublist]
min(first, min(values))
max(last, max(values))
我正在运行一些基准测试,似乎第二种解决方案比第一种解决方案略快。 但是,我还将这两个版本与其他海报发布的代码进行了比较。
solution one: 0.648876905441
solution two: 0.634277105331
solution three (TigerhawkT3): 2.14495801926
solution four (Def_Os): 1.07884407043
solution five (leewangzhong): 0.635314941406
基于随机生成的100万个键的字典。 我认为leewangzhong的解决方案非常好。除了上面显示的时间,在接下来的实验中,它的结果比我的第二个解决方案(我们谈论的是几毫秒)要快一些,例如:
solution one: 0.678879022598
solution two: 0.62641787529
solution three: 2.15943193436
solution four: 1.05863213539
solution five: 0.611482858658
Itertools真是一个很棒的模块!
答案 2 :(得分:0)
您可以使用一些理解来简化代码。
first = min(min(data) for (key, data) in my_data.items() if "LastFirst_" in key)
last = max(max(data) for (key, data) in my_data.items() if "LastFirst_" in key)
答案 3 :(得分:0)
max
和.values()
函数被重载以获取多个值(当您使用它时)或一个值序列,因此您可以传入迭代(例如列表)并获取最小值或者最多。
此外,如果您只对这些值感兴趣,请使用itervalues()
或.items()
。如果您对两者都感兴趣,请使用.iteritems()
或.iter
。 (在Python 3中,没有for
- 版本。)
如果你有很多序列,你可以使用itertools.chain
使它们成为一个很长的可迭代序列。您也可以在单个理解中使用多个import itertools
def flatten1(iterables):
# The "list" is necessary, because we want to use this twice
# but `chain` returns an iterator, which can only be used once.
return list(itertools.chain(*iterables))
# Note: The "(" ")" indicates that this is an iterator, not a list.
valid_lists = (v for k,v in my_data.iteritems() if "LastFirst_" in k)
valid_values = flatten1(valid_lists)
# Alternative: [w for w in v for k,v in my_data.iteritems() if "LastFirst_" in k]
first = min(valid_values)
last = max(valid_values)
print first, last
手动将它们串起来,但这可能会令人反感。
max
如果最大和最小元素不在dict中,那么编码器应该决定做什么,但我建议他们考虑允许min
/ None
的默认行为(可能是引发异常,或default
值),而不是试图猜测上限或下限。任何一个都会更像Pythonic。
在Python 3中,您可以指定max(valid_values, default=10000)
参数,例如self
。
答案 4 :(得分:0)
my_data = {'LastFirst_a': [1, 2, 34000], 'LastFirst_b': [-12000, 1, 5]}
first = 10000
last = -10000
# Note: replace .items() with .iteritems() if you're using Python 2.
relevant_data = [el for k, v in my_data.items() for el in v if "LastFirst_" in k]
# maybe faster:
# relevant_data = [el for k, v in my_data.items() for el in v if k.startswith("LastFirst_")]
first = max(first, max(relevant_data))
last = min(last, min(relevant_data))
print(first, last)