繁体   English   中英

比较两个列表并找到最喜欢的对

[英]comparing two lists and finding most preferred pairs

我有两个这样的清单:

people: ["rob", "candice", "candice", "rob", "arnold", "ben", "ben", "ben", "arnold"]
fruit: ["orange", "orange", "mango", "mango", "orange", "orange", "banana", "mango", "banana"]

这两个列表分别代表人和他们喜欢的水果。 它们是长度相等的列表。

我被要求从水果清单中查找(仅使用列表而不使用字典),这是大多数人喜欢的那对水果?

这里的预期结果将是("mango","orange") 我非常感谢您对此逻辑的帮助。 我想自己编写代码。

我应该使用嵌套for循环吗? zip并行运行两个列表? 这是我正在处理的一些代码。 尝试列出所有水果,不确定我的方向是否正确:

def findpair(fruit, people):
    eachfruit=[]
    seen=set()
       for i in fruit
           for j in people
               if i not in seen             
               seen.add(i)

如果您想知道最喜欢哪种水果,您要做的就是数数水果 无需与这里的人们配对水果。

自行学习编码的方法是将每个水果的计数器保留在字典中,然后按值对字典进行排序以获取最受欢迎的水果,然后再获取最受欢迎的水果,依此类推:

counts = {}

for fruit in fruits:
    counts[fruit] = counts.get(fruit, 0) + 1

top_fruits = sorted(counts, key=lambda fruit: counts[fruit], reversed=True)
print top_fruits[:2]

Pythonic方法是使用collections.Counter()对象,并为您进行计数:

top_two = [fruit for fruit, count in Counter(fruits).most_common(2)]

产生:

>>> from collections import Counter
>>> fruits = ["orange", "orange", "mango", "mango", "orange", "orange", "banana", "mango", "banana"]
>>> [fruit for fruit, count in Counter(fruits).most_common(2)]
['orange', 'mango']

如果您需要数对水果 ,则需要做更多的工作。 collections.defaultdict()可以帮助您收集每个人的喜好,它使用frozensetset来仅查看唯一的配对,而itertools.combinations() frozenset每个人生成一对水果:

from collections import defaultdict, Counter
from itertools import combinations

likes = defaultdict(set)
for person, fruit in zip(persons, fruits):
    likes[person].add(fruit)

counts = Counter()
for person in likes:
    for combo in combinations(likes[person], 2):
        counts[frozenset(combo)] += 1

result = counts.most_common(1)[0][0]

演示:

>>> from collections import defaultdict, Counter
>>> from itertools import combinations
>>> persons = ["rob", "candice", "candice", "rob", "arnold", "ben", "ben", "ben", "arnold"]
>>> fruits = ["orange", "orange", "mango", "mango", "orange", "orange", "banana", "mango", "banana"]
>>> likes = defaultdict(set)
>>> for person, fruit in zip(persons, fruits):
...     likes[person].add(fruit)
... 
>>> likes
defaultdict(<type 'set'>, {'ben': set(['orange', 'mango', 'banana']), 'rob': set(['orange', 'mango']), 'candice': set(['orange', 'mango']), 'arnold': set(['orange', 'banana'])})
>>> counts = Counter()
>>> for person in likes:
...     for combo in combinations(likes[person], 2):
...         counts[frozenset(combo)] += 1
... 
>>> counts.most_common(1)[0][0]
frozenset(['orange', 'mango'])

实际上,预期结果应该是('orange', 'mango') 这是满足您需求的代码:

people = ["rob", "candice", "candice", "rob", "arnold", "ben", "ben", "ben", "arnold"]
fruit = ["orange", "orange", "mango", "mango", "orange", "orange", "banana", "mango", "banana"]
class People(object):
    def __init__(self, people, fruits):
        self.people = people
        self.fruits = fruits
        self.fruits_list = []
        for i in range(len(fruits)):
            if not hasattr(self, fruits[i]):
                setattr(self, fruits[i], 0)
            if fruits[i] not in self.fruits_list:
                self.fruits_list.append(fruits[i])
    def getFruits(self):
        for i in range(len(self.fruits)):
            setattr(self, self.fruits[i], getattr(self, self.fruits[i])+1)
        fruits_number = []
        for i in range(len(self.fruits_list)):
            fruits_number.append(getattr(self, self.fruits_list[i]))
        max_list = sorted(fruits_number, reverse=True)[0:2]
        f = ()
        for i in max_list:
            f += (self.fruits_list[fruits_number.index(i)],)
        return f
obj = People(people, fruit)
obj.getFruits()

此类使用peoplefruit两个列表作为参数,它遍历fruits列表并检查类实例是否对每个水果都有一个属性,如果没有设置属性,则还将每个水果追加到列表fruits_list ,确保没有重复。 有一种方法getFruits()循环遍历fruits列表,每次遇到水果时将1添加到fruit属性,然后循环遍历fruit_list并将水果数附加到称为fruits_number的列表中并获取最大的2个数字列表中的(存储在max_list变量),那么它遍历max_list并添加水果的值fruits_list具有相同索引作为数max_list storedifruit_number ,终于该元组f被返回。

class Counter(dict):
    '''Dict subclass for counting hashable items.  Sometimes called a bag
    or multiset.  Elements are stored as dictionary keys and their counts
    are stored as dictionary values.

因此,使用Counter是使用dict。

仅使用列表,您可以通过以下方式进行操作:

1 sort list
2 go through list, if the fruit same as prev one, counter + 1, otherwise save the counter and fruit in result list
3 sort result list by counter and output result

================================================== ===========

def play():
     fruit = ["orange", "orange", "mango", "mango", "orange", "orange", "banana", "mango", "banana"]
     fruit.sort()
     result = []
     last = None

     for f in fruit:
         if last != f:
             result.append([0, f])
         else:
             result[-1][0] += 1

         last = f

      result.sort(reverse=True)

      print result[:2]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM