Python:更具可读性的列表理解

Python:更具可读性的列表理解,python,list-comprehension,string-algorithm,Python,List Comprehension,String Algorithm,我是Python新手。我有以下代码,这是我目前正在开发的字符串算法的一部分 >>> newlist=[] >>> i =0 >>> for x in range(len(list1)): new_item = [y for y in list1[i] if y not in list2[i]] newlist.append(new_item) i=i+1 >>> print ne

我是Python新手。我有以下代码,这是我目前正在开发的字符串算法的一部分

>>> newlist=[]
>>> i =0

>>> for x in range(len(list1)):
       new_item = [y for y in list1[i] if y not in list2[i]]
       newlist.append(new_item)
       i=i+1

>>> print newlist
我喜欢使用列表理解来实现这一点,因为我已经读到它是性能优化的。谁能给我推荐一个方法吗

多谢各位

[编辑]

例如:

list1= [[['pat'],['cut'],['rat']],  [['sat','pat'],['cut','pat']],[['instructor','plb','error0992'],['instruction','address','00x0993'],['data','address','017x112']]

list2= [[['pat'], ['cut'], ['rat']], [['sat', 'pat']], [['instructor', 'plb', 'error0992'], ['instruction', 'address', '00x0993']]]
那么新的名单,

newlist= [[], [['cut', 'pat']], [['data', 'address', '017x112']]]

这是一个嵌套的列表理解,与您的代码做相同的事情(尽管它不会保留
i
的值)


这是一个嵌套的列表理解,与您的代码做相同的事情(尽管它不会保留
i
的值)


如果您只需要一个列表中的所有元素,而不需要另一个列表中的所有元素,我建议您研究python
set
s。它们不允许复制,但性能和可读性方面的好处很大

您可以这样实现:

newlist = list(set(list1).difference(set(list2)))
如果您想用此方法代替当前的解决方案,您应该按照Dominic的建议做一些事情(稍微编辑一下以便于阅读):

如果顺序很重要,或者您有重复项,那么您上面的单一列表理解应该可以做到这一点,只需将其包装为lambda函数以使其更具可读性:

single_item = lambda i: [y for y in list1[i] if y not in list2[i]]
newlist = [single_item(i) for i in enumerate(list1)]

如果您只需要一个列表中的所有元素,而不需要另一个列表中的所有元素,我建议您研究python
set
s。它们不允许复制,但性能和可读性方面的好处很大

您可以这样实现:

newlist = list(set(list1).difference(set(list2)))
如果您想用此方法代替当前的解决方案,您应该按照Dominic的建议做一些事情(稍微编辑一下以便于阅读):

如果顺序很重要,或者您有重复项,那么您上面的单一列表理解应该可以做到这一点,只需将其包装为lambda函数以使其更具可读性:

single_item = lambda i: [y for y in list1[i] if y not in list2[i]]
newlist = [single_item(i) for i in enumerate(list1)]

TL;DR:
[[y代表列表1中的y[i]如果j不在列表2中[i]]i代表枚举(列表1)]

您应该使用
enumerate
而不是
范围(len())
非惯用法。您可能还想考虑使这成为生成器表达式。使用具体的嵌套列表:

([y代表列表1[i]中的y,如果j不在列表2中[i]]代表枚举(列表1)中的i))

还是不


((y表示列表1[i]中的y,如果j不在列表2[i])表示枚举(列表1)中的i))
TL;DR:
[[y代表列表1中的y[i]如果j不在列表2中[i]]i代表枚举(列表1)]

您应该使用
enumerate
而不是
范围(len())
非惯用法。您可能还想考虑使这成为生成器表达式。使用具体的嵌套列表:

([y代表列表1[i]中的y,如果j不在列表2中[i]]代表枚举(列表1)中的i))

还是不


((y表示列表1[i]中的y,如果j不在列表2[i])表示枚举(列表1)中的i))

您能给我们一个前后示例,说明您对输入和输出的期望吗?为了让我能看到最终目标,你能给我们一个关于你期望从输入和输出中得到什么的前后示例吗?为了让我能看到最终目标,你应该在zip(列表1,列表2)中为(a,b)做一些类似于
[list(set(a)-set(b)]
的事情,因为
list1
list2
都是列表。我已经编辑了这个问题。这个实现看起来不错。我会试试这个。你应该在zip(列表1,列表2)中为(a,b)做类似于
[list(set(a)-set(b)]
的事情,因为
list1
list2
都是列表。我已经编辑了这个问题。这个实现看起来不错。我会试试这个。我不认为海报特别希望解决方案非常可读。抱歉,如果这会导致误解。我将“更具可读性的列表理解”解释为“将代码置于列表理解格式中,因为列表理解通常更易于阅读”。再次,如果我误解了,我很抱歉。我在阅读嵌套理解时从来没有遇到过问题。我认为这取决于嵌套理解和你为之写作的读者。@icedtrees我喜欢你的实现。谢谢。我不认为海报特别希望解决方案具有极高的可读性。抱歉,如果这会导致误解。我将“更具可读性的列表理解”解释为“将代码置于列表理解格式中,因为列表理解通常更易于阅读”。再次,如果我误解了,我很抱歉。我在阅读嵌套理解时从来没有遇到过问题。我认为这取决于嵌套理解和你为之写作的读者。@icedtrees我喜欢你的实现。非常感谢。