[英]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()
可以帮助您收集每个人的喜好,它使用frozenset
和set
来仅查看唯一的配对,而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()
此类使用people
和fruit
两个列表作为参数,它遍历fruits
列表并检查类实例是否对每个水果都有一个属性,如果没有设置属性,则还将每个水果追加到列表fruits_list
,确保没有重复。 有一种方法getFruits()
循环遍历fruits
列表,每次遇到水果时将1添加到fruit属性,然后循环遍历fruit_list
并将水果数附加到称为fruits_number
的列表中并获取最大的2个数字列表中的(存储在max_list
变量),那么它遍历max_list
并添加水果的值fruits_list
具有相同索引作为数max_list stored
在i
在fruit_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.