use*_*060 -2 python list-comprehension list
我有一个for循环,它将字符串列表中每个元素的子字符串与另一个字符串列表中的元素进行比较。
mylist = []
for x in list1:
mat = False
for y in list2:
if x[:-14] in y:
mat = True
if not mat:
mylist.append(x)
Run Code Online (Sandbox Code Playgroud)
不过,我想将其放入列表理解中(for 循环并不符合我的口味),但无法找到一种方法来计算mat.
我尝试过以下变体:
mylist = [x for x in list1 if x[:-14] in list2]
Run Code Online (Sandbox Code Playgroud)
但这与原始循环的逻辑不同。有没有办法将原来的 for 循环改造成列表理解?
正如所写,不,您不能直接将其编写为列表理解,因为在理解中没有像 之类的中间变量的位置mat。
但是,如果您重构中间变量以将其计算为单独的函数:
def check_match(x, seq):
"checks if text excluding the last 14 characters of string `x` is a substring of any elements of the list `seq`"
mat = False
for y in seq:
if x[:-14] in y:
mat = True
return mat
mylist = []
for x in list1:
mat = check_match(x, list2)
if not mat:
mylist.append(x)
Run Code Online (Sandbox Code Playgroud)
现在我们可以将函数调用直接移至条件中if not,在您的特定情况下,您也可以应用函数的逻辑any,以便可以简化您的函数:
def check_match(x, seq):
"checks if text excluding the last 14 characters of string `x` is a substring of any elements of the list `seq`"
return any((x[:-14] in y) for y in seq)
mylist = []
for x in list1:
if not check_match(x, list2):
mylist.append(x)
Run Code Online (Sandbox Code Playgroud)
现在我们没有任何中间变量,转换就非常简单了:
mylist = [x for x in list1 if not any((x[:-14] in y) for y in list2)]
# or if your case can't be easily refactored into a single expression just leave it as a separate function
# mylist = [x for x in list1 if not check_match(x, list2)]
Run Code Online (Sandbox Code Playgroud)
或者,如果将其保留为一个单独的函数,该函数返回要保留True的元素,并且仅将元素作为参数,则可以直接使用:filter
def is_not_in_list2(x):
"checks if x[:-14] is *not* a substring of any elements of `list2`"
return not any((x[:-14] in y) for y in list2)
myiterator = filter(is_not_in_list2, list1)
# you can loop over `myiterator` once and it will be very memory efficient, or if you need it as a proper list just pass it to the list constructor
mylist = list(myiterator)
Run Code Online (Sandbox Code Playgroud)