Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.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
具有多个列表和if-else条件的Python列表理解_Python_List_Conditional_List Comprehension - Fatal编程技术网

具有多个列表和if-else条件的Python列表理解

具有多个列表和if-else条件的Python列表理解,python,list,conditional,list-comprehension,Python,List,Conditional,List Comprehension,我想循环两个同样长的集合,并确定每个集合中的元素是否也在一个数组中 这是一个黑客问题,我已经解决了。然而,我正在使用Hackerrank进一步了解Python。我一直在学习列表理解,虽然我确实相信我是如何试图使用它来被认为是糟糕的生产代码,但我仍然想探索语言语法的可能性,以获取我自己的知识 这是设置它的代码: n, m = map(int, input().split()) arr = list(map(int, input().split())) A = set(map(int, input(

我想循环两个同样长的集合,并确定每个集合中的元素是否也在一个数组中

这是一个黑客问题,我已经解决了。然而,我正在使用Hackerrank进一步了解Python。我一直在学习列表理解,虽然我确实相信我是如何试图使用它来被认为是糟糕的生产代码,但我仍然想探索语言语法的可能性,以获取我自己的知识

这是设置它的代码:

n, m = map(int, input().split())
arr = list(map(int, input().split()))
A = set(map(int, input().split()))
B = set(map(int, input().split()))
任务是为a和arr中的每个元素输出一个值为+1的整数,为B和arr中的每个元素输出一个值为-1的整数

样本输入:

3 2
1 5 3
3 1
5 7
样本输出:

1
这将达到所需的结果:

print(sum([1 for a in A if a in arr]) + sum([-1 for b in B if b in arr]))
然而,这更接近我想要实现的目标:

sum([1 if a in arr else -1 if b in arr for a, b in zip(A, B)])
编辑这实际上更接近:

print(sum(1 if a in arr -1 if b in arr for a, b in zip(A, B)))
正如您所看到的,这两个代码都是一行代码,所以这并不是为了减少代码,而是为了理解列表理解和Python代码的可能性。如果这是不可能的,甚至是不好的做法,我也非常感兴趣

这是Hackerrank链接:
首先,放弃对清单的理解;使用生成器表达式将值直接输入到sum中:

sum(1 for a in A if a in arr)
如果A是一个集合,请使用提取公共值,然后取结果的长度:

这比尝试测试每个值的arr要快。不过,这确实会首先生成一个新的集合对象,但您之前创建了一个列表,所以这并没有多大区别

在这一点上,仅减去第二个长度要简单得多:

len(A.intersection(arr)) - len(B.intersection(arr))
通过在arr上循环并根据A或B测试arr中的每个值,可以避免创建集合;这也更快,因为集合成员资格测试是O1恒定时间:

sum(1 if v in A else -1 if v in B else 0 for v in arr)
如果值a不存在,则您为集合a中的每个值测试a in arr的方法需要对arr进行完整列表扫描;这使得在线性时间问题上针对列表a进行成员资格测试,并且对a中的每个值和B中的每个值都这样做,因此最终得到OA+B*N==OKN时间。根据集合测试arr中的每个值仅在*1==准时


此外,如果arr中的值不是唯一的,那么您的方法实际上会导致错误的答案;你只能数一次快乐或不快乐的数字,而问题要求每次出现时都要数;使用生成器表达式将值直接输入到sum中:

sum(1 for a in A if a in arr)
如果A是一个集合,请使用提取公共值,然后取结果的长度:

这比尝试测试每个值的arr要快。不过,这确实会首先生成一个新的集合对象,但您之前创建了一个列表,所以这并没有多大区别

在这一点上,仅减去第二个长度要简单得多:

len(A.intersection(arr)) - len(B.intersection(arr))
通过在arr上循环并根据A或B测试arr中的每个值,可以避免创建集合;这也更快,因为集合成员资格测试是O1恒定时间:

sum(1 if v in A else -1 if v in B else 0 for v in arr)
如果值a不存在,则您为集合a中的每个值测试a in arr的方法需要对arr进行完整列表扫描;这使得在线性时间问题上针对列表a进行成员资格测试,并且对a中的每个值和B中的每个值都这样做,因此最终得到OA+B*N==OKN时间。根据集合测试arr中的每个值仅在*1==准时


此外,如果arr中的值不是唯一的,那么您的方法实际上会导致错误的答案;您只需计算快乐或不快乐的数字一次,而问题要求每次出现时都要对它们进行计数。

将数组转换为设置并获取交点如何

s = set(arr)
print(len(A.intersection(s)) - len(B.intersection(s)))
编辑:
此解决方案不适用于arr中的重复值

将数组转换为设置并获取交点如何

s = set(arr)
print(len(A.intersection(s)) - len(B.intersection(s)))
编辑:
此解决方案不适用于arr中的重复值

您的解决方案很棒,但这里有一个陷阱。这两组数字使用的是集合数据结构,数组使用的是列表。当在列表顶部应用in运算符时,您正在执行on搜索,而在一个集合中,相同的操作在python中是Ologn,平均大小写是O1!。所以你的总时间复杂度是O2*m*n=Om*n。您可以以相反的方式进行搜索,例如:

对于数组中的每个元素,如果A中的元素为+1,如果B中的元素为-1

这个问题的总复杂度为*2*logm=On*logm


关于python时间复杂性的更多信息

您的解决方案很棒,但这里有一个陷阱。这两组数字使用的是集合数据结构,数组使用的是列表。当在列表顶部应用in运算符时,您正在执行on搜索,而在一个集合中,相同的操作在python中是Ologn,平均大小写是O1!。所以你的总时间复杂度是O2*m*n=Om*n。您可以以相反的方式进行搜索,例如:

对于数组中的每个元素,如果 A然后是+1,如果B中的元素是-1

这个问题的总复杂度为*2*logm=On*logm


关于python时间复杂性的更多信息

这是我在使用列表理解时提交的答案。这是必要的,因为数组可能具有相同元素的倍数,因此计数需要反映这一点

n, m = map(int, input().split())
arr = list(input().split())
A, B = set(input().split()), set(input().split())
print(sum([(e in A) - (e in B) for e in arr]))

这是我提交的答案,因为它使用列表理解作为我的第一个想法。这是必要的,因为数组可能具有相同元素的倍数,因此计数需要反映这一点

n, m = map(int, input().split())
arr = list(input().split())
A, B = set(input().split()), set(input().split())
print(sum([(e in A) - (e in B) for e in arr]))

解决此问题的最有效方法可能是将A和B的项作为键放入字典中,值为1或-1取决于它们来自哪个集合。这将允许您扫描列表arr,并轻松获得要添加到总和的值:

ab_dict = {a: 1 for a in A}
ab_dict.update((b, -1) for b in B)

result = sum(ab_dict.get(x, 0) for x in arr)

计算结果的计算复杂度与在生成器表达式sum1 if x in a else-1 if x in b else 0 for x in arr中使用两个条件运算符相同,但是,由于每个项目只有一个dict查找,而不是两个集合成员测试,因此速度应该会更快一些。

解决此问题的最有效方法可能是将A和B的项目作为键放入字典中,值为1或-1取决于它们来自哪个集合。这将允许您扫描列表arr,并轻松获得要添加到总和的值:

ab_dict = {a: 1 for a in A}
ab_dict.update((b, -1) for b in B)

result = sum(ab_dict.get(x, 0) for x in arr)


计算结果的计算复杂度与在生成器表达式sum1 if x in a else-1 if x in b else 0 for x in arr中使用两个条件运算符相同,但是,由于每个项目只有一个dict查找,而不是两个集合成员测试,因此速度应该会更快一些。

如果要立即将列表转换为集合,为什么还要使用列表理解?您可以使用集合理解。顺便说一句,我想您不需要列表理解,如果我记得很清楚的话,sum接受任何iterable,这样您就可以删除[]并将其传递给生成器。@spectras我不知道这一点。我将在不理解列表的情况下尝试它。我还注意到,else if是不正确的,因为它应该是两个if语句,所以第二个条件被检查,即使第一个条件不是真的,我正在阅读,我认为尝试在一个容器中进行两个求和有点误导,因为你从不同的容器中求和不同的东西。这不仅是因为如果不以奇怪的方式扭曲数据,它将无法工作,而且从逻辑的角度来看,它也没有意义。如果要立即将列表转换为一个集合,为什么要使用列表理解呢?您可以使用集合理解。顺便说一句,我想您不需要列表理解,如果我记得很清楚的话,sum接受任何iterable,这样您就可以删除[]并将其传递给生成器。@spectras我不知道这一点。我将在不理解列表的情况下尝试它。我还注意到,else if是不正确的,因为它应该是两个if语句,所以第二个条件被检查,即使第一个条件不是真的,我正在阅读,我认为尝试在一个容器中进行两个求和有点误导,因为你从不同的容器中求和不同的东西。这不仅是因为如果不以奇怪的方式扭曲数据,它将无法正常工作,而且从逻辑的角度来看,它也没有意义。我也在考虑这个问题,但我认为如果arr可以有重复的值,而这些值应该被多次计数,那么它就不能正常工作。@Blckknght>实际上,问题陈述并没有说它们应该被计算一次以上。对于数组中的每个整数,如果∊ A、 你给你的幸福增加了1”。所以这只是1,不管它在A中出现多少次。@RaviKumar:但是您可以使用arr=[1,1]和A=set[1],B=set[0]进行测试。输出应该是2,但这段代码会生成1。@OP提供的MartiInputers解决方案会迭代A和B的每个元素,并检查arr中是否存在元素。因此,对于您的示例,答案应该是1。@RaviKumar:我知道OP发布了什么,但这并不意味着他们的答案是正确的。我也在考虑这个问题,但我认为,如果arr可以有重复的值,而这些值应该不止一次计数,那么它就不能正常工作。@Blckknght>事实上,问题陈述并没有说它们应该不止一次计数。对于数组中的每个整数,如果∊ A、 你给你的幸福增加了1”。所以这只是1,不管它在A中出现多少次。@RaviKumar:但是您可以使用arr=[1,1]和A=set[1],B=set[0]进行测试。输出应该是2,但这段代码生成1。@OP提供的MartiInputers解决方案迭代A和B的每个元素,并检查arr中是否存在元素。因此,对于您的示例,答案应该是1。@RaviKumar:我知道OP发布了什么,但是,这并不意味着他们的答案是正确的。因为单位值只是被加和减,所以这更有意义,使用集合th
eory更干净。因为单位值只是被加和减,这更有意义,集合论的使用也更干净。我只是在你发表文章前几分钟才发现这一点。这是一个很好的观点。我只是在你发帖前几分钟才发现这一点。这是一个伟大的观点。