How to compare each item in a list with the rest, only once?

后端 未结 5 511
误落风尘
误落风尘 2020-12-07 09:02

Say I have an array/list of things I want to compare. In languages I am more familiar with, I would do something like

for (int i = 0, i < mylist.size(); i         


        
相关标签:
5条回答
  • 2020-12-07 09:14

    This code will count frequency and remove duplicate elements:

    from collections import Counter
    
    str1='the cat sat on the hat hat'
    
    int_list=str1.split();
    
    unique_list = []
    for el in int_list:
    
        if el not in unique_list:
            unique_list.append(el)
        else:
            print "Element already in the list"
    
    print unique_list
    
    c=Counter(int_list)
    
    c.values()
    
    c.keys()
    
    print c
    
    0 讨论(0)
  • 2020-12-07 09:22

    Of course this will generate each pair twice as each for loop will go through every item of the list.

    You could use some itertools magic here to generate all possible combinations:

    import itertools
    for a, b in itertools.combinations(mylist, 2):
        compare(a, b)
    

    itertools.combinations will pair each element with each other element in the iterable, but only once.


    You could still write this using index-based item access, equivalent to what you are used to, using nested for loops:

    for i in range(len(mylist)):
        for j in range(i + 1, len(mylist)):
            compare(mylist[i], mylist[j])
    

    Of course this may not look as nice and pythonic but sometimes this is still the easiest and most comprehensible solution, so you should not shy away from solving problems like that.

    0 讨论(0)
  • 2020-12-07 09:23

    I think using enumerate on the outer loop and using the index to slice the list on the inner loop is pretty Pythonic:

    for index, this in enumerate(mylist):
        for that in mylist[index+1:]:
            compare(this, that)
    
    0 讨论(0)
  • 2020-12-07 09:34

    Your solution is correct, but your outer loop is still longer than needed. You don't need to compare the last element with anything else because it's been already compared with all the others in the previous iterations. Your inner loop still prevents that, but since we're talking about collision detection you can save the unnecessary check.

    Using the same language you used to illustrate your algorithm, you'd come with something like this:

    for (int i = 0, i < mylist.size() - 1; ++i)
        for (int j = i + 1, j < mylist.size(); --j)
            compare(mylist[i], mylist[j])
    
    0 讨论(0)
  • 2020-12-07 09:35

    Use itertools.combinations(mylist, 2)

    mylist = range(5)
    for x,y in itertools.combinations(mylist, 2):
        print x,y
    
    0 1
    0 2
    0 3
    0 4
    1 2
    1 3
    1 4
    2 3
    2 4
    3 4
    
    0 讨论(0)
提交回复
热议问题