Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 比较列表中实例的属性,然后添加到新列表_Python_Algorithm_Loops_Class_Instance - Fatal编程技术网

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
总和+=喜欢/不喜欢/不喜欢[每]
如果不在目录或总和中