加快速度。 (使用条件在相同迭代中的最小值,最大值)

时间:2015-06-25 17:09:39

标签: python for-loop iteration max min

我想询问是否/如何重写下面这些行,以便更快地运行。

*( - 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

5 个答案:

答案 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)