更好/更快地循环设置或列表?

时间:2013-02-27 00:26:46

标签: python list loops set

如果我有一个包含许多重复项的python列表,并且我想遍历每个项目,但不是通过重复项,那么最好使用一个集合(如set(mylist)中所示,或者找到另一种方式创建一个没有重复的列表?我只想循环遍历列表并检查重复项,但我认为这是set()在初始化时的作用。

因此,如果mylist = [3,1,5,2,4,4,1,4,2,5,1,3]而我真的只想循环[1,2,3,4,5](顺序无关紧要),我应该使用set(mylist)还是别的?

在上一个示例中可以使用替代方法,因为列表包含其最小值和最大值之间的每个整数,我可以遍历range(min(mylist),max(mylist))set(mylist)。在这种情况下,我是否应该尽量避免使用set?另外,发现minmax会比创建set慢吗?


在上一个示例中,set更快:

from numpy.random import random_integers
ids = random_integers(1e3,size=1e6)

def set_loop(mylist):
    idlist = []
    for id in set(mylist):
        idlist.append(id)
    return idlist

def list_loop(mylist):
    idlist = []
    for id in range(min(mylist),max(mylist)):
        idlist.append(id)
    return idlist

%timeit set_loop(ids)
#1 loops, best of 3: 232 ms per loop

%timeit list_loop(ids)
#1 loops, best of 3: 408 ms per loop

5 个答案:

答案 0 :(得分:37)

只需使用set即可。它的语义正是你想要的:一系列独特的物品。

从技术上讲,你将在列表中迭代两次:一次创建集合,一次用于实际循环。但是你可以用其他任何方法做同样多的工作或更多。

答案 1 :(得分:9)

set是你想要的,所以你应该使用set。试图聪明地引入一些细微的错误,比如忘记添加一个max(mylist)!代码防守。当你确定它太慢时,担心什么会更快。

range(min(mylist), max(mylist) + 1)  # <-- don't forget to add 1

答案 2 :(得分:5)

为简单起见:newList = list(set(oldList))

但如果你想获得速度/订购/优化,那么有更好的选择:http://www.peterbe.com/plog/uniqifiers-benchmark

答案 3 :(得分:5)

虽然uint64_t v = 0x123456789LL; swap(v, 0, 1) 可能是你想要的结构,但问题是什么更快。列表更快。您的示例代码没有准确地比较setset,因为您正在从列表转换为 list中的集,然后您正在创建set_loop,您将在 list中循环。迭代的集合和列表应该提前构建并在内存中,并且只需循环查看迭代时哪个数据结构更快:

list_loop

答案 4 :(得分:1)

我的列表变化很大,循环两次会花费很多时间而且在第二次循环一个集合而不是列表时更多,因为我们知道迭代一个集合比列表慢。

我认为你需要generatorset的力量。

def first_test():

    def loop_one_time(my_list):
        # create a set to keep the items.
        iterated_items = set()
        # as we know iterating over list is faster then list.
        for value in my_list: 
            # as we know checking if element exist in set is very fast not
            # metter the size of the set.
            if value not in iterated_items:  
                iterated_items.add(value) # add this item to list
                yield value


    mylist = [3,1,5,2,4,4,1,4,2,5,1,3]

    for v in loop_one_time(mylist):pass



def second_test():
    mylist = [3,1,5,2,4,4,1,4,2,5,1,3]
    s = set(mylist)
    for v in s:pass


import timeit

print(timeit.timeit('first_test()', setup='from __main__ import first_test', number=10000))
print(timeit.timeit('second_test()', setup='from __main__ import second_test', number=10000))

out put:

   0.024003583388435043
   0.010424674188938422

注意:保证此技术顺序