Python 比较列表中实例的属性,然后添加到新列表
我想建立一个算法,其中我有一个人员实例列表,例如:Python 比较列表中实例的属性,然后添加到新列表,python,algorithm,loops,class,instance,Python,Algorithm,Loops,Class,Instance,我想建立一个算法,其中我有一个人员实例列表,例如: worst_office = [jim, michael, pam, toby, oscar, kevin, kelly, ryan, jan] 现在,所有这些实例都有一个属性,其中一个是他们喜欢的人,例如jim喜欢pam,另一个属性是他们不喜欢的两个人的列表。那么,比较列表中所有实例的属性的最有效方法是什么,然后只与那些在新组中有一个他们喜欢的人,或者一个不喜欢一个喜欢,而不是两个不喜欢的人一起创建并查找所有新列表的数量 例如 迈克尔讨厌
worst_office = [jim, michael, pam, toby, oscar, kevin, kelly, ryan, jan]
现在,所有这些实例都有一个属性,其中一个是他们喜欢的人,例如jim喜欢pam,另一个属性是他们不喜欢的两个人的列表。那么,比较列表中所有实例的属性的最有效方法是什么,然后只与那些在新组中有一个他们喜欢的人,或者一个不喜欢一个喜欢,而不是两个不喜欢的人一起创建并查找所有新列表的数量
例如
- 迈克尔讨厌简和托比,但喜欢吉姆
- 托比讨厌迈克尔和凯文,但喜欢帕姆
def check(first_list, second_list):
for each_employee in first_list:
name = each_employee.get_name()
is_disliked = False
is_liked = False
count = 0
if second_list:
for j in second_list:
if name in j.get_dislikes():
is_disliked = True
count += 1
elif name == j.get_likes():
is_liked = True
if (is_disliked and not is_liked) or count > 1:
if each_employee in second_list:
second_list.remove(each_employee)
else:
if each_employee in second_list:
pass
else:
second_list += [each_employee, ]
def checking(office_list):
z = [1]
best_office = []
check(office_list, best_office)
check(best_office.copy(), best_office)
if len(best_office) >= 9:
#This is to make sure only lists with more than 9 employees are selected
for i in best_office:
print(i.get_name())
print('-----------------------')
perm_employees = itertools.permutations(worst_office)
for x in perm_employees:
checking(x)
工作起来相当快如果没有@functools.lru_缓存(maxsize=None),则需要0.15秒 缓存为0.06 我认为有一个更聪明的答案,这只是蛮力
import functools
import itertools as it
import time
start_time = time.time()
worst_office = ["jim", "michael", "pam", "toby", "oscar", "kevin", "kelly", "ryan", "jan"]
like_dislike_dict = {}
like_dislike_dict[("jim", "toby")] = -1
like_dislike_dict[("jim", "oscar")] = -1
like_dislike_dict[("jim", "michael")] = 1
like_dislike_dict[("michael", "pam")] = 1
like_dislike_dict[("michael", "toby")] = -1
like_dislike_dict[("michael", "oscar")] = -1
like_dislike_dict[("pam", "toby")] = -1
like_dislike_dict[("pam", "oscar")] = -1
like_dislike_dict[("pam", "jim")] = 1
like_dislike_dict[("toby", "jim")] = -1
like_dislike_dict[("toby", "michael")] = -1
like_dislike_dict[("toby", "oscar")] = 1
like_dislike_dict[("oscar", "jim")] = -1
like_dislike_dict[("oscar", "michael")] = -1
like_dislike_dict[("oscar", "kevin")] = 1
like_dislike_dict[("kevin", "ryan")] = -1
like_dislike_dict[("kevin", "jim")] = -1
like_dislike_dict[("kevin", "toby")] = 1
like_dislike_dict[("kelly", "jim")] = -1
like_dislike_dict[("kelly", "michael")] = -1
like_dislike_dict[("kelly", "ryan")] = 1
like_dislike_dict[("ryan", "jim")] = -1
like_dislike_dict[("ryan", "michael")] = -1
like_dislike_dict[("ryan", "jan")] = 1
like_dislike_dict[("jan", "jim")] = -1
like_dislike_dict[("jan", "michael")] = -1
like_dislike_dict[("jan", "kelly")] = 1
def partition(collection):
# from https://stackoverflow.com/questions/19368375/set-partitions-in-python
if len(collection) == 1:
yield [ collection ]
return
first = collection[0]
for smaller in partition(collection[1:]):
# insert `first` in each of the subpartition's subsets
for n, subset in enumerate(smaller):
yield smaller[:n] + [[ first ] + subset] + smaller[n+1:]
# put `first` in its own subset
yield [ [ first ] ] + smaller
@functools.lru_cache(maxsize=None)
def valid_list(l):
for name in l:
per_set = it.product([name], l)
per_set = frozenset(per_set)
if not valid_set(per_set):
return False
return True
def valid_set(t):
sum = 0
in_dict = False
for per in t:
if per in like_dislike_dict:
in_dict = True
sum+= like_dislike_dict[per]
if not in_dict or sum<0:
return False
return True
partition_list = list(partition(worst_office))
valids = []
for partition_option in partition_list:
valid = True
for part in partition_option:
if not valid_list(frozenset(part)):
valid = False
if valid:
valids.append(partition_option)
print(valids)
print(list(partition_list[-4]))
print("--- %s seconds ---" % (time.time() - start_time))
导入工具
按原样导入itertools
导入时间
开始时间=time.time()
最差办公室=[“吉姆”、“迈克尔”、“潘”、“托比”、“奥斯卡”、“凯文”、“凯利”、“瑞安”、“简”]
like_love_dict={}
喜欢/不喜欢/不喜欢(吉姆/托比)=-1
喜欢/不喜欢/不喜欢/不喜欢
喜欢,不喜欢,不喜欢(吉姆,迈克尔)
喜欢/不喜欢/不喜欢/不喜欢
喜欢/不喜欢/不喜欢(迈克尔/托比)=-1
喜欢、不喜欢、不喜欢(迈克尔、奥斯卡)=-1
like_love_dict[(“pam”,“toby”)]=-1
喜欢/不喜欢/不喜欢/不喜欢
喜欢、不喜欢、不听话[(“潘”、“吉姆”)]=1
喜欢/不喜欢/不喜欢单词[(“托比”,“吉姆”)]=-1
喜欢/不喜欢/不喜欢[托比/迈克尔]=-1
喜欢、不喜欢、不喜欢(托比、奥斯卡)
喜欢/不喜欢/不喜欢
喜欢/不喜欢/不喜欢
喜欢/不喜欢/不喜欢(奥斯卡、凯文)]=1
喜欢/不喜欢/不喜欢(凯文、瑞安)=-1
喜欢/不喜欢/不喜欢[凯文/吉姆]=-1
喜欢、不喜欢(凯文、托比)=1
喜欢/不喜欢/不喜欢/不喜欢
喜欢你不喜欢你的话[(“凯利”,“迈克尔”)]=-1
like_love_dict[(“kelly”,“ryan”)]=1
like_love_dict[(“ryan”,“jim”)]=-1
like_love_dict[(“ryan”,“michael”)]=-1
like_love_dict[(“ryan”,“jan”)]=1
喜欢/不喜欢/不喜欢单词[(“jan”,“jim”)]=-1
喜欢/不喜欢/不喜欢
喜欢/不喜欢/不喜欢
def分区(集合):
#从https://stackoverflow.com/questions/19368375/set-partitions-in-python
如果len(集合)==1:
收益[集合]
返回
第一个=集合[0]
对于分区中较小的(集合[1:]):
#在每个子分区的子集中插入“first”
对于n,枚举中的子集(较小):
产生更小的[:n]+[[第一个]+子集]+更小的[n+1:]
#将'first'放在它自己的子集中
收益率[[第一]]+更小
@functools.lru\u缓存(maxsize=None)
def有效_列表(l):
对于l中的名称:
per_set=it.product([name],l)
每集=冻结集(每集)
如果无效\u集(每个\u集):
返回错误
返回真值
def有效_设置(t):
总和=0
in_dict=False
对于每英寸t:
如果在喜欢或不喜欢的情况下:
in_dict=True
总和+=喜欢/不喜欢/不喜欢[每]
如果不在目录或总和中